diff --git a/examples/Client/Client.ino b/examples/Client/Client.ino index 4f57310..e75fb41 100644 --- a/examples/Client/Client.ino +++ b/examples/Client/Client.ino @@ -55,13 +55,13 @@ void setup() } - +bool dataReady = false; void loop() { EthernetMaketClient::tick(); uint32_t currentMillis = millis(); - if (currentMillis - ttt > 75) + if (currentMillis - ttt > 25) { digitalToggle(PC13); ttt = currentMillis; // Обновляем время @@ -71,34 +71,29 @@ void loop() { previousMillis = currentMillis; - // client.stop(); // Завершаем предыдущее соединение - // connectStatus = CONNECT_START; // функция коннекта - // client.connect(serverIP, SERVER_PORT); - // client.setData(buf, sizeof(buf)); - // client() + Serial.println("connectNonBlock"); + client.connectNonBlock(serverIP, SERVER_PORT); + client.connectStatus = CONNECT_START; - if (client.connectNonBlock(serverIP, SERVER_PORT) == CONNECT_CONNECTED) + dataReady = true; + } + + if(dataReady && client.isConnected()) + { + for (size_t i = 0; i < 3; i++) { - for (size_t i = 0; i < 3; i++) + client.dataWrite((uint8_t *)&packetCounter, sizeof(packetCounter)); + + // Print the packet being sent + Serial.print("Sending packet: "); + for (size_t j = 0; j < sizeof(packetCounter); j++) { - client.dataWrite((uint8_t *)&packetCounter, sizeof(packetCounter)); - - // Print the packet being sent - Serial.print("Sending packet: "); - for (size_t j = 0; j < sizeof(packetCounter); j++) - { - Serial.print(((uint8_t *)&packetCounter)[j], HEX); - Serial.print(" "); - } - Serial.println(); - packetCounter++; + Serial.print(((uint8_t *)&packetCounter)[j], HEX); + Serial.print(" "); } + Serial.println(); + packetCounter++; } - else - { - Serial.println("Failed to connect to server"); - client.stop(); - } - + dataReady = false; } } \ No newline at end of file diff --git a/src/EthernetOverride/TCP.cpp b/src/EthernetOverride/TCP.cpp index 35872b3..34689fe 100644 --- a/src/EthernetOverride/TCP.cpp +++ b/src/EthernetOverride/TCP.cpp @@ -2,25 +2,27 @@ #include "utility/w5500.h" #include "utility/socket.h" -std::vector EthernetMaketClient::instances; - +std::list& EthernetMaketClient::getInstances() { + static std::list instances; // Список создаётся при первом доступе + return instances; +} EthernetMaketClient::EthernetMaketClient() { _sock = MAX_SOCK_NUM; - instances.push_back(this); + getInstances().push_back(this); } EthernetMaketClient::EthernetMaketClient(uint8_t sock) { _sock = sock; - instances.push_back(this); + getInstances().push_back(this); } EthernetMaketClient::~EthernetMaketClient() { - instances.erase(std::remove(instances.begin(), instances.end(), this), instances.end()); + getInstances().remove(this); } void EthernetMaketClient::tick() { - for (EthernetMaketClient* client : instances) { + for (EthernetMaketClient* client : getInstances()) { client->tick_(); } } @@ -28,49 +30,61 @@ void EthernetMaketClient::tick() { ConnectionStatusSimple EthernetMaketClient::connectNonBlock(IPAddress ip, uint16_t port) { dstIP = ip; dstPort = port; - if (_sock != MAX_SOCK_NUM) { - // Serial.println(F("connectNonBlock")); - uint8_t status_ = status(); - switch (status_) { - case SnSR::CLOSED: - // Serial.println(F("CLOSED")); + + // if(connectStatus == CONNECT_IDLE){ + // connectStatus = CONNECT_START; + // } + + if (_sock != MAX_SOCK_NUM) { + uint8_t status_ = status(); + switch (status_) { + case SnSR::CLOSED: + Serial.println(F("connectNonBlock(): CONNECT_FAIL (CLOSED)")); + _sock = MAX_SOCK_NUM; + return CONNECT_FAIL; + break; + case SnSR::ESTABLISHED: + Serial.println(F("connectNonBlock(): CONNECT_SUCCESS (ESTABLISHED)")); + return CONNECT_SUCCESS; + break; + default: + Serial.println(F("connectNonBlock(): CONNECT_CONNECTING (Default)")); + return CONNECT_CONNECTING; + break; + } + } + + for (int i = 0; i < MAX_SOCK_NUM; i++) { + uint8_t s = w5500.readSnSR(i); + if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT || s == SnSR::CLOSE_WAIT) { + _sock = i; + break; + } + } + + if (_sock == MAX_SOCK_NUM) { + Serial.println(F("connectNonBlock(): CONNECT_FAIL (No available socket)")); + return CONNECT_FAIL; + } + + Serial.print("sock: "); + Serial.println(_sock); + + _srcport++; + if (_srcport == 0) _srcport = 1024; + socket(_sock, SnMR::TCP, _srcport, 0); + + if (!::connect(_sock, rawIPAddress(ip), port)) { + Serial.println(F("connectNonBlock(): CONNECT_FAIL (Connect failed)")); _sock = MAX_SOCK_NUM; return CONNECT_FAIL; - break; - case SnSR::ESTABLISHED: - // Serial.println(F("ESTABLISHED")); - return CONNECT_SUCCESS; - break; - default: - // Serial.print(F("status ")); - // Serial.println(status_,HEX); - return CONNECT_CONNECTING; - break; } - } - for (int i = 0; i < MAX_SOCK_NUM; i++) { - uint8_t s = w5500.readSnSR(i); - if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT || s == SnSR::CLOSE_WAIT) { - _sock = i; - break; - } - } - if (_sock == MAX_SOCK_NUM) - return CONNECT_FAIL; - - _srcport++; - if (_srcport == 0) _srcport = 1024; - socket(_sock, SnMR::TCP, _srcport, 0); - - if (!::connect(_sock, rawIPAddress(ip), port)) { - _sock = MAX_SOCK_NUM; - return CONNECT_FAIL; - } - - return CONNECT_CONNECTING; + Serial.println(F("connectNonBlock(): CONNECT_CONNECTING (Connection initiated)")); + return CONNECT_CONNECTING; } + bool EthernetMaketClient::isConnected() const { return connectStatus == CONNECT_CONNECTED; } @@ -89,28 +103,31 @@ void EthernetMaketClient::close(){ } void EthernetMaketClient::tick_(){ - // Подключаемся к серверу switch (connectStatus) { case CONNECT_START: - startConnection = millis(); + Serial.println("CONNECT_START"); + startConnectionTime = millis(); connectStatus = CONNECT_CONNECTING; close(); - Serial.println("\n\nConnecting..."); + Serial.println("CONNECT_CONNECTING..."); break; case CONNECT_CONNECTING: - if (millis() - startConnection >= connectionTimeout) - { + if (millis() - startConnectionTime >= connectionTimeout) + { connectStatus = CONNECT_FAIL; break; } break; case CONNECT_FAIL: + Serial.println("CONNECT_FAIL"); Serial.print("Failed to connect to server in "); Serial.println(isNonBlocking ? "non-blocking mode" : "blocking mode"); + Serial.println("\n"); connectStatus = CONNECT_STOP_START; break; case CONNECT_SUCCESS: + Serial.println("CONNECT_SUCCESS"); Serial.print("Connected to server in "); Serial.println(isNonBlocking ? "non-blocking mode" : "blocking mode"); lastActivityTime = millis(); @@ -140,6 +157,7 @@ void EthernetMaketClient::tick_(){ break; case CONNECT_STOP_START: + Serial.println("CONNECT_STOP_START"); dstIP = IPAddress(0,0,0,0); dstPort = 0; disconnect(); @@ -148,23 +166,27 @@ void EthernetMaketClient::tick_(){ break; case CONNECT_STOP_WAITING: + Serial.println("CONNECT_STOP_WAITING"); if (millis() - stopStartTime >= stopTimeout) { close(); // Окончательное закрытие сокета после таймаута - connectStatus = (dataSize > 0) ? CONNECT_START : CONNECT_IDLE; + connectStatus = CONNECT_IDLE; } else { // Проверяем состояние сокета для завершения разрыва uint8_t status_ = status(); if (status_ == SnSR::CLOSED || status_ == SnSR::CLOSE_WAIT) { close(); // Закрываем при достижении состояния - connectStatus = (dataSize > 0) ? CONNECT_START : CONNECT_IDLE; + connectStatus = CONNECT_IDLE; } } + if(connectStatus == CONNECT_IDLE) { + Serial.println("CONNECT_IDLE\n\n"); + } break; case CONNECT_IDLE: - if(dataSize){ - connectStatus = CONNECT_START; - } + // if(dataSize){ + // connectStatus = CONNECT_START; + // } break; default: @@ -175,9 +197,6 @@ void EthernetMaketClient::tick_(){ { case CONNECT_START: case CONNECT_CONNECTING: - if(dstIP == IPAddress(0,0,0,0) || dstPort == 0) - break; - if (isNonBlocking) { connectStatus = connectNonBlock(dstIP, dstPort); @@ -237,7 +256,7 @@ bool EthernetMaketClient::dataWrite(){ bool ret = false; if(dataSize) { lastActivityTime = millis(); - if(write((uint8_t *)&dataPtr, dataSize)){ + if(write(dataPtr, dataSize)){ dataPtr = nullptr; dataSize = 0; // Очищаем размер данных ret = true; @@ -248,7 +267,7 @@ bool EthernetMaketClient::dataWrite(){ } bool EthernetMaketClient::dataWrite(uint8_t* data, uint16_t dataSize, bool override) { - if (dataSize == 0 || override || (dataPtr == nullptr && this->dataSize == 0)) { + if (this->dataSize == 0 || override) { this->dataPtr = data; this->dataSize = dataSize; return dataWrite(); @@ -259,32 +278,35 @@ bool EthernetMaketClient::dataWrite(uint8_t* data, uint16_t dataSize, bool overr } -bool EthernetMaketClient::send(uint8_t* data, uint16_t dataSize, IPAddress ip, uint16_t port) { - this->dataPtr = data; - this->dataSize = dataSize; +// bool EthernetMaketClient::send(uint8_t* data, uint16_t dataSize, IPAddress ip, uint16_t port) { +// this->dataPtr = data; +// this->dataSize = dataSize; +// dstIP = ip; +// dstPort = port; - switch (connectStatus) { - case CONNECT_CONNECTED: - if(dataWrite()){ - onSendSuccess(); - } - // Если подключено, отправляем данные - return true; +// switch (connectStatus) { +// case CONNECT_CONNECTED: +// if(dataWrite()){ +// onSendSuccess(); +// } +// // Если подключено, отправляем данные +// return true; - case CONNECT_STOP_WAITING: - case CONNECT_STOP_START: - return false; // Ожидаем завершения разрыва +// case CONNECT_STOP_WAITING: +// case CONNECT_STOP_START: +// return false; // Ожидаем завершения разрыва - case CONNECT_FAIL: - case CONNECT_IDLE: - connectNonBlock(ip, port); - connectStatus = CONNECT_START; // Начинаем новое подключение - return false; // Подключение инициировано +// // case CONNECT_FAIL: +// case CONNECT_IDLE: +// connectNonBlock(ip, port); +// connectStatus = CONNECT_START; // Начинаем новое подключение +// return false; // Подключение инициировано - default: - return false; // Пока ждём подключения - } -} +// default: +// return false; // Пока ждём подключения +// } +// return false; +// } void EthernetMaketClient::setOnSendSuccess(const std::function& callback) { onSendSuccess = callback; @@ -293,3 +315,15 @@ void EthernetMaketClient::setOnSendSuccess(const std::function& callback void EthernetMaketClient::resetOnSendSuccess() { onSendSuccess = []() {}; } + +void EthernetMaketClient::stop(){ + connectStatus = CONNECT_STOP_START; +} + +void EthernetMaketClient::startConnection(IPAddress ip, uint16_t port, bool nonBlock){ + dstIP = ip; + dstPort = port; + isNonBlocking = nonBlock; + connectNonBlock(dstIP, dstPort); + connectStatus = CONNECT_START; +}; diff --git a/src/EthernetOverride/TCP.h b/src/EthernetOverride/TCP.h index ca81623..a01158b 100644 --- a/src/EthernetOverride/TCP.h +++ b/src/EthernetOverride/TCP.h @@ -1,7 +1,7 @@ #ifndef __MAKET_TCP_H__ #define __MAKET_TCP_H__ -#include +#include #include #include "../util/config.h" @@ -9,7 +9,7 @@ class EthernetMaketClient : public EthernetClient { protected: uint32_t lastActivityTime = 0; // Время последней активности const uint16_t timeout = 300; // Таймаут неактивности в миллисекундах - uint32_t startConnection = 0; + uint32_t startConnectionTime = 0; const uint16_t connectionTimeout = 350; uint32_t stopStartTime = 0; // Время начала состояния CONNECT_IDLE const uint32_t stopTimeout = 300; // Таймаут для закрытия сокета в состоянии CONNECT_IDLE @@ -17,32 +17,39 @@ protected: std::function onSendSuccess = []() {}; bool isNonBlocking = true; // Флаг для определения режима подключения - ConnectionStatusSimple connectStatus = CONNECT_IDLE; - uint8_t* dataPtr; + uint8_t* dataPtr = nullptr; uint16_t dataSize = 0; IPAddress dstIP; uint16_t dstPort; + bool dataWrite(); - static std::vector instances; + static std::list& getInstances(); // Ленивое создание списка + void tick_(); + public: + ConnectionStatusSimple connectStatus = CONNECT_IDLE; EthernetMaketClient(); EthernetMaketClient(uint8_t sock); ~EthernetMaketClient(); + ConnectionStatusSimple connectNonBlock(IPAddress ip, uint16_t port); + void startConnection(IPAddress ip, uint16_t port, bool nonBlock = true); + + bool dataWrite(uint8_t* data, uint16_t dataSize, bool override = false); + // bool send(uint8_t* data, uint16_t dataSize, IPAddress ip, uint16_t port); + void disconnect(); void close(); + void stop(); + bool isConnected() const; static void tick(); - bool send(uint8_t* data, uint16_t dataSize, IPAddress ip, uint16_t port); - - bool isConnected() const; void setOnSendSuccess(const std::function& callback); void resetOnSendSuccess(); - bool dataWrite(uint8_t* data, uint16_t dataSize, bool override = false); }; #endif // __MAKET_TCP_H__