Procedural reference

This commit is contained in:
2024-11-20 15:22:17 +03:00
parent b6e2fb1356
commit eee3b84b8e
11 changed files with 580 additions and 0 deletions

View File

@ -0,0 +1,24 @@
#ifndef __ETHERNETMAKET_H__
#define __ETHERNETMAKET_H__
#include "Ethernet3.h"
enum ConnectionStatusSimple{
CONNECT_FAIL = 0,
CONNECT_SUCCESS = 1,
CONNECT_CONNECTING = 2,
CONNECT_START = 3,
CONNECT_IDLE = 4,
CONNECT_CONNECTED = 5,
CONNECT_STOP_START = 6,
CONNECT_STOP_WAITING = 7,
};
#include "EthernetOverride/TCP.h"
#endif // __ETHERNETMAKET_H__

View File

@ -0,0 +1,64 @@
#include "Server.h"
#include "utility/w5500.h"
#include "utility/socket.h"
void EthernetMaketServer::setServerHandler(std::function<void(EthernetMaketClient)> handler)
{
serverHandler = handler;
}
void EthernetMaketServer::resetServerHandler()
{
serverHandler = [](EthernetMaketClient sclient) {};
}
EthernetMaketClient EthernetMaketServer::available(int sock)
{
accept(sock);
EthernetMaketClient client(sock);
if (EthernetClass::_server_port[sock] == _port &&
(client.status() == SnSR::ESTABLISHED ||
client.status() == SnSR::CLOSE_WAIT))
{
if (client.available())
{
return client;
}
}
return 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())
{
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;
}
}

View File

@ -0,0 +1,24 @@
#ifndef __MAKET_SERVER_H__
#define __MAKET_SERVER_H__
#include "Ethernet3.h"
#include "TCP.h"
#include <functional>
class EthernetMaketServer : EthernetServer
{
private:
EthernetClient available();
void accept(int sock);
std::function<void(EthernetMaketClient)> serverHandler = [](EthernetMaketClient sclient){};
public:
using EthernetServer::EthernetServer;
EthernetMaketClient available(int sock);
void setServerHandler(std::function<void(EthernetMaketClient)> handler);
void resetServerHandler();
void begin(int sock);
};
#endif // __MAKET_SERVER_H__

View File

@ -0,0 +1,86 @@
#include "TCP.h"
#include "utility/w5500.h"
#include "utility/socket.h"
ConnectionStatusSimple EthernetMaketClient::connectNonBlock(IPAddress ip, uint16_t port) {
if (_sock != MAX_SOCK_NUM) {
// Serial.println(F("connectNonBlock"));
uint8_t status_ = status();
switch (status_) {
case SnSR::CLOSED:
// Serial.println(F("CLOSED"));
_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;
}
void EthernetMaketClient::disconnect(){
if (_sock == MAX_SOCK_NUM)
return;
::disconnect(_sock);
}
void EthernetMaketClient::close(){
if (_sock == MAX_SOCK_NUM)
return;
::close(_sock);
_sock = MAX_SOCK_NUM;
}
// void EthernetMaketClient::stop() {
// if (_sock == MAX_SOCK_NUM)
// return;
// // attempt to close the connection gracefully (send a FIN to other side)
// disconnect(_sock);
// unsigned long start = millis();
// // wait a second for the connection to close
// uint8_t s;
// do {
// s = status();
// if (s == SnSR::CLOSED)
// break; // exit the loop
// delay(1);
// } while (millis() - start < 1000);
// // if it hasn't closed, close it forcefully
// if (status() != SnSR::CLOSED)
// close(_sock);
// EthernetClass::_server_port[_sock] = 0;
// _sock = MAX_SOCK_NUM;
// }

View File

@ -0,0 +1,17 @@
#ifndef __MAKET_TCP_H__
#define __MAKET_TCP_H__
#include "../EthernetMaket.h"
class EthernetMaketClient : public EthernetClient
{
public:
using EthernetClient::EthernetClient;
ConnectionStatusSimple connectNonBlock(IPAddress ip, uint16_t port);
// void stop() override;
void disconnect();
void close();
};
#endif // __MAKET_TCP_H__

View File

@ -0,0 +1,62 @@
#include "UDP.h"
#include "utility/w5500.h"
#include "utility/socket.h"
void sendUDP_tick(SOCKET s, ConnectionStatusSimple &status)
{
switch (status)
{
case CONNECT_START:
w5500.execCmdSn(s, Sock_SEND);
status = CONNECT_CONNECTING;
break;
case CONNECT_CONNECTING:
if ((w5500.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK)
{
if (w5500.readSnIR(s) & SnIR::TIMEOUT)
{
/* +2008.01 [bj]: clear interrupt */
w5500.writeSnIR(s, (SnIR::SEND_OK | SnIR::TIMEOUT));
status = CONNECT_FAIL;
break;
}
else
{
status = CONNECT_CONNECTING;
break;
}
}
else
{
status = CONNECT_SUCCESS;
w5500.writeSnIR(s, SnIR::SEND_OK);
break;
}
break;
case CONNECT_FAIL:
status = CONNECT_IDLE;
break;
case CONNECT_SUCCESS:
status = CONNECT_IDLE;
break;
case CONNECT_IDLE:
break;
default:
break;
}
}
void EthernetMaketUDP::endPacketNonBlock()
{
_status = CONNECT_START;
sendUDP_tick(_sock, _status);
return;
}
void EthernetMaketUDP::tick(){
sendUDP_tick(_sock, _status);
}

View File

@ -0,0 +1,15 @@
#ifndef __MAKET_UDP_H__
#define __MAKET_UDP_H__
#include "../EthernetMaket.h"
class EthernetMaketUDP : EthernetUDP
{
private:
ConnectionStatusSimple _status; // статус соединения
public:
using EthernetUDP::EthernetUDP;
void endPacketNonBlock();
void tick();
};
#endif // __MAKET_UDP_H__