[realtek-ambz] Add new WiFiServer library
This commit is contained in:
@@ -151,9 +151,13 @@ SoftwareSerial | ❌
|
||||
SPI | ❌
|
||||
Wire | ❌
|
||||
**OTHER LIBRARIES** |
|
||||
Wi-Fi Station | ✔️
|
||||
Wi-Fi Access Point | ❌
|
||||
Wi-Fi Events | ❌
|
||||
Wi-Fi Client (SSL) | ✔️ (❌)
|
||||
Wi-Fi Server | ❌
|
||||
SPIFFS | ❌
|
||||
BLE | -
|
||||
Wi-Fi (SSL) | ✔️ (❌)
|
||||
HTTP | ❌
|
||||
NTP | ❌
|
||||
OTA | ❌
|
||||
|
||||
@@ -28,6 +28,10 @@ class IWiFiClient : public Client {
|
||||
|
||||
IWiFiClient(int sock) {}
|
||||
|
||||
~IWiFiClient() {
|
||||
stop();
|
||||
}
|
||||
|
||||
virtual int connect(IPAddress ip, uint16_t port, int32_t timeout) = 0;
|
||||
virtual int connect(const char *host, uint16_t port, int32_t timeout) = 0;
|
||||
|
||||
@@ -66,4 +70,5 @@ class IWiFiClient : public Client {
|
||||
virtual uint16_t localPort(int sock) const = 0;
|
||||
|
||||
using Print::write;
|
||||
using Client::stop;
|
||||
};
|
||||
|
||||
@@ -20,39 +20,47 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <api/Server.h>
|
||||
#include <api/Print.h>
|
||||
|
||||
#include "WiFiClient.h"
|
||||
|
||||
class IWiFiServer : public Server {
|
||||
#include <type_traits>
|
||||
|
||||
template <typename TWiFiClient, typename = std::enable_if<std::is_base_of<IWiFiClient, TWiFiClient>::value>>
|
||||
|
||||
class IWiFiServer : public Print { // arduino::Server is useless anyway
|
||||
public:
|
||||
void listenOnLocalhost() {}
|
||||
|
||||
IWiFiServer(uint16_t port = 80, uint8_t max_clients = 4) {}
|
||||
IWiFiServer(uint16_t port = 80, uint8_t maxClients = 4) {}
|
||||
|
||||
~IWiFiServer() {
|
||||
end();
|
||||
stop();
|
||||
}
|
||||
|
||||
WiFiClient available();
|
||||
|
||||
WiFiClient accept() {
|
||||
return available();
|
||||
}
|
||||
TWiFiClient available() {
|
||||
return accept();
|
||||
};
|
||||
|
||||
virtual operator bool() = 0;
|
||||
|
||||
void begin(uint16_t port = 0);
|
||||
void begin(uint16_t port, int reuse_enable);
|
||||
void end();
|
||||
void close();
|
||||
void stop();
|
||||
virtual bool begin(uint16_t port = 0, bool reuseAddr = true) = 0;
|
||||
virtual void end() = 0;
|
||||
virtual TWiFiClient accept() = 0;
|
||||
|
||||
int setTimeout(uint32_t seconds);
|
||||
void stopAll();
|
||||
void setNoDelay(bool nodelay);
|
||||
bool getNoDelay();
|
||||
bool hasClient();
|
||||
void close() {
|
||||
end();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
end();
|
||||
}
|
||||
|
||||
virtual int setTimeout(uint32_t seconds) = 0;
|
||||
virtual void stopAll() = 0;
|
||||
virtual void setNoDelay(bool noDelay) = 0;
|
||||
virtual bool getNoDelay() = 0;
|
||||
virtual bool hasClient() = 0;
|
||||
|
||||
size_t write(uint8_t data) {
|
||||
return write(&data, 1);
|
||||
|
||||
5
arduino/libretuya/compat/WiFiAP.h
Normal file
5
arduino/libretuya/compat/WiFiAP.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// ESP32 WiFi examples use WiFiAP.h include
|
||||
|
||||
#include <WiFi.h>
|
||||
@@ -29,6 +29,7 @@ extern "C" {
|
||||
#include <diag.h>
|
||||
|
||||
extern void *pvPortMalloc( size_t xWantedSize );
|
||||
extern void *os_zalloc( size_t xWantedSize );
|
||||
extern void vPortFree( void *pv );
|
||||
extern void *pvPortReAlloc( void *pv, size_t xWantedSize );
|
||||
extern size_t xPortGetFreeHeapSize( void );
|
||||
@@ -79,7 +80,7 @@ void sys_info(void) {
|
||||
}
|
||||
|
||||
|
||||
void * malloc(size_t size)
|
||||
/* void * malloc(size_t size)
|
||||
{
|
||||
void * ret;
|
||||
if((ret = pvPortMalloc(size)) == NULL)
|
||||
@@ -99,7 +100,7 @@ void * zalloc(size_t size)
|
||||
void *calloc(size_t count, size_t size)
|
||||
{
|
||||
return zalloc(count * size);
|
||||
}
|
||||
} */
|
||||
|
||||
void free(void *pv)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include "WiFiClient.h"
|
||||
#include "WiFiServer.h"
|
||||
|
||||
class WiFiClass : public IWiFiClass,
|
||||
public IWiFiGenericClass,
|
||||
|
||||
@@ -21,9 +21,9 @@ bool WiFiClass::softAP(const char *ssid, const char *passphrase, int channel, bo
|
||||
|
||||
if (passphrase) {
|
||||
strcpy((char *)ap_password, passphrase);
|
||||
wifi.security_type = RTW_SECURITY_WPA2_AES_PSK;
|
||||
wifi.password = ap_password;
|
||||
wifi.password_len = strlen(passphrase);
|
||||
ap.security_type = RTW_SECURITY_WPA2_AES_PSK;
|
||||
ap.password = ap_password;
|
||||
ap.password_len = strlen(passphrase);
|
||||
}
|
||||
|
||||
dhcps_deinit();
|
||||
@@ -96,6 +96,7 @@ bool WiFiClass::softAPdisconnect(bool wifiOff) {
|
||||
|
||||
uint8_t WiFiClass::softAPgetStationNum() {
|
||||
// TODO
|
||||
// the struct is at wifi_conf.c:2576
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +1,27 @@
|
||||
#include "WiFiClient.h"
|
||||
#include "WiFiPriv.h"
|
||||
|
||||
// I think I don't understand how that works.
|
||||
// For some reason, LwIP uses a different (extern) errno,
|
||||
// while this macro refers to a function __errno, which
|
||||
// reads a totally different variable.
|
||||
#undef errno
|
||||
#include <lwip/arch.h>
|
||||
|
||||
// disable #defines removing lwip_ prefix
|
||||
#undef LWIP_COMPAT_SOCKETS
|
||||
#define LWIP_COMPAT_SOCKETS 0
|
||||
#include <lwip/sockets.h>
|
||||
|
||||
WiFiClient::WiFiClient() : _sock(-1), _connected(false) {
|
||||
_timeout = WIFI_CLIENT_CONNECT_TIMEOUT;
|
||||
WiFiClient::WiFiClient() {
|
||||
DiagPrintf("WiFiClient()\r\n");
|
||||
_sock = -1;
|
||||
_connected = false;
|
||||
_rxBuffer = NULL;
|
||||
_timeout = WIFI_CLIENT_CONNECT_TIMEOUT;
|
||||
}
|
||||
|
||||
WiFiClient::WiFiClient(int sock) {
|
||||
_sock = sock;
|
||||
_connected = true;
|
||||
_rxBuffer.reset(new LwIPRxBuffer(sock));
|
||||
_timeout = WIFI_CLIENT_CONNECT_TIMEOUT;
|
||||
}
|
||||
|
||||
WiFiClient::~WiFiClient() {
|
||||
stop();
|
||||
_rxBuffer = new LwIPRxBuffer(sock);
|
||||
_timeout = WIFI_CLIENT_CONNECT_TIMEOUT;
|
||||
}
|
||||
|
||||
WiFiClient &WiFiClient::operator=(const IWiFiClient &other) {
|
||||
stop();
|
||||
// _sock = other._sock;
|
||||
// _connected = other._connected;
|
||||
// _rxBuffer = other._rxBuffer;
|
||||
WiFiClient *oth = (WiFiClient *)&other;
|
||||
_sock = oth->_sock;
|
||||
_connected = oth->_connected;
|
||||
_rxBuffer = oth->_rxBuffer;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -115,7 +104,8 @@ int WiFiClient::connect(IPAddress ip, uint16_t port, int32_t timeout) {
|
||||
lwip_close(_sock);
|
||||
_sock = sock;
|
||||
_connected = true;
|
||||
_rxBuffer.reset(new LwIPRxBuffer(_sock));
|
||||
free(_rxBuffer);
|
||||
_rxBuffer = new LwIPRxBuffer(_sock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -264,7 +254,8 @@ void WiFiClient::stop() {
|
||||
lwip_close(_sock);
|
||||
_sock = -1;
|
||||
_connected = false;
|
||||
_rxBuffer = NULL;
|
||||
free(_rxBuffer);
|
||||
_rxBuffer = NULL;
|
||||
}
|
||||
|
||||
uint8_t WiFiClient::connected() {
|
||||
@@ -292,7 +283,7 @@ uint8_t WiFiClient::connected() {
|
||||
return _connected;
|
||||
}
|
||||
|
||||
IPAddress getaddr(int sock, int (*func)(int, struct sockaddr *, socklen_t *)) {
|
||||
IPAddress __attribute__((noinline)) getaddr(int sock, int (*func)(int, struct sockaddr *, socklen_t *)) {
|
||||
struct sockaddr addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
func(sock, &addr, &len);
|
||||
@@ -300,7 +291,7 @@ IPAddress getaddr(int sock, int (*func)(int, struct sockaddr *, socklen_t *)) {
|
||||
return IPAddress((uint32_t)(s->sin_addr.s_addr));
|
||||
}
|
||||
|
||||
uint16_t getport(int sock, int (*func)(int, struct sockaddr *, socklen_t *)) {
|
||||
uint16_t __attribute__((noinline)) getport(int sock, int (*func)(int, struct sockaddr *, socklen_t *)) {
|
||||
struct sockaddr addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
func(sock, &addr, &len);
|
||||
|
||||
@@ -2,18 +2,16 @@
|
||||
|
||||
#include <api/LwIPRxBuffer.h>
|
||||
#include <api/WiFiClient.h>
|
||||
#include <memory>
|
||||
|
||||
class WiFiClient : public IWiFiClient {
|
||||
private:
|
||||
int _sock;
|
||||
bool _connected;
|
||||
std::shared_ptr<LwIPRxBuffer> _rxBuffer;
|
||||
LwIPRxBuffer *_rxBuffer;
|
||||
|
||||
public:
|
||||
WiFiClient();
|
||||
WiFiClient(int sock);
|
||||
~WiFiClient();
|
||||
|
||||
int connect(IPAddress ip, uint16_t port);
|
||||
int connect(const char *host, uint16_t port);
|
||||
|
||||
@@ -16,12 +16,11 @@ bool WiFiClass::mode(WiFiMode mode) {
|
||||
// initialize wifi first
|
||||
LwIP_Init();
|
||||
reset_wifi_struct();
|
||||
wifi_manager_init();
|
||||
// wifi_manager_init(); // these are events!
|
||||
_initialized = true;
|
||||
}
|
||||
if (currentMode) {
|
||||
// stop wifi to change mode
|
||||
dhcps_deinit();
|
||||
if (wifi_off() != RTW_SUCCESS)
|
||||
return false;
|
||||
vTaskDelay(20);
|
||||
@@ -29,10 +28,6 @@ bool WiFiClass::mode(WiFiMode mode) {
|
||||
|
||||
if (wifi_on((rtw_mode_t)mode) != RTW_SUCCESS)
|
||||
return false;
|
||||
|
||||
if (mode & WIFI_MODE_AP) {
|
||||
dhcps_init(NETIF_RTW_STA);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -52,7 +47,7 @@ WiFiStatus WiFiClass::status() {
|
||||
|
||||
bool WiFiClass::enableSTA(bool enable) {
|
||||
WiFiMode currentMode = getMode();
|
||||
if ((currentMode & WIFI_MODE_STA != 0) != enable) {
|
||||
if (((currentMode & WIFI_MODE_STA) != 0) != enable) {
|
||||
return mode((WiFiMode)(currentMode ^ WIFI_MODE_STA));
|
||||
}
|
||||
return true;
|
||||
@@ -60,7 +55,7 @@ bool WiFiClass::enableSTA(bool enable) {
|
||||
|
||||
bool WiFiClass::enableAP(bool enable) {
|
||||
WiFiMode currentMode = getMode();
|
||||
if ((currentMode & WIFI_MODE_AP != 0) != enable) {
|
||||
if (((currentMode & WIFI_MODE_AP) != 0) != enable) {
|
||||
return mode((WiFiMode)(currentMode ^ WIFI_MODE_AP));
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -18,6 +18,18 @@ extern "C" {
|
||||
#define WIFI_CLIENT_SELECT_TIMEOUT 1000
|
||||
#define WIFI_CLIENT_FLUSH_BUF_SIZE 1024
|
||||
|
||||
// I think I don't understand how that works.
|
||||
// For some reason, LwIP uses a different (extern) errno,
|
||||
// while this macro refers to a function __errno, which
|
||||
// reads a totally different variable.
|
||||
#undef errno
|
||||
#include <lwip/arch.h>
|
||||
|
||||
// disable #defines removing lwip_ prefix
|
||||
#undef LWIP_COMPAT_SOCKETS
|
||||
#define LWIP_COMPAT_SOCKETS 0
|
||||
#include <lwip/sockets.h>
|
||||
|
||||
#include <autoconf.h>
|
||||
#include <dhcp/dhcps.h>
|
||||
#include <lwip/api.h>
|
||||
|
||||
104
arduino/realtek-ambz/libraries/WiFi/WiFiServer.cpp
Normal file
104
arduino/realtek-ambz/libraries/WiFi/WiFiServer.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
#include "WiFiServer.h"
|
||||
#include "WiFiPriv.h"
|
||||
|
||||
WiFiServer::WiFiServer(uint16_t port, uint8_t maxClients)
|
||||
: _sock(-1), _sockAccepted(-1), _port(port), _maxClients(maxClients), _active(false), _noDelay(false) {}
|
||||
|
||||
WiFiServer::operator bool() {
|
||||
return _active;
|
||||
}
|
||||
|
||||
bool WiFiServer::begin(uint16_t port, bool reuseAddr) {
|
||||
if (_active)
|
||||
return true;
|
||||
if (port)
|
||||
_port = port;
|
||||
|
||||
_sock = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (_sock < 0)
|
||||
return false;
|
||||
|
||||
int enable = reuseAddr;
|
||||
lwip_setsockopt(_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
addr.sin_port = htons(_port);
|
||||
|
||||
if (lwip_bind(_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
||||
return false;
|
||||
|
||||
if (lwip_listen(_sock, _maxClients) < 0)
|
||||
return false;
|
||||
|
||||
lwip_fcntl(_sock, F_SETFL, O_NONBLOCK);
|
||||
_active = true;
|
||||
_noDelay = false;
|
||||
_sockAccepted = -1;
|
||||
}
|
||||
|
||||
void WiFiServer::end() {
|
||||
if (_sock == -1)
|
||||
return;
|
||||
lwip_close(_sock);
|
||||
_sock = -1;
|
||||
_active = -1;
|
||||
}
|
||||
|
||||
WiFiClient WiFiServer::accept() {
|
||||
if (!_active)
|
||||
return WiFiClient();
|
||||
|
||||
int sock;
|
||||
if (_sockAccepted) {
|
||||
sock = _sockAccepted;
|
||||
_sockAccepted = -1;
|
||||
} else {
|
||||
struct sockaddr_in addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
sock = lwip_accept(_sock, (struct sockaddr *)&addr, &len);
|
||||
}
|
||||
|
||||
if (sock >= 0) {
|
||||
int enable = 1;
|
||||
if (lwip_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)) == ERR_OK) {
|
||||
enable = _noDelay;
|
||||
if (lwip_setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)) == ERR_OK) {
|
||||
return WiFiClient(sock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return WiFiClient();
|
||||
}
|
||||
|
||||
int WiFiServer::setTimeout(uint32_t seconds) {
|
||||
struct timeval tv;
|
||||
tv.tv_sec = seconds;
|
||||
tv.tv_usec = 0;
|
||||
if (lwip_setsockopt(_sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
|
||||
return -1;
|
||||
return lwip_setsockopt(_sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||
}
|
||||
|
||||
void WiFiServer::setNoDelay(bool noDelay) {
|
||||
_noDelay = noDelay;
|
||||
}
|
||||
|
||||
bool WiFiServer::getNoDelay() {
|
||||
return _noDelay;
|
||||
}
|
||||
|
||||
bool WiFiServer::hasClient() {
|
||||
if (_sockAccepted >= 0) {
|
||||
return true;
|
||||
}
|
||||
struct sockaddr_in addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
_sockAccepted = lwip_accept(_sock, (struct sockaddr *)&addr, &len);
|
||||
if (_sockAccepted >= 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
35
arduino/realtek-ambz/libraries/WiFi/WiFiServer.h
Normal file
35
arduino/realtek-ambz/libraries/WiFi/WiFiServer.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <api/WiFiServer.h>
|
||||
|
||||
#include "WiFiClient.h"
|
||||
|
||||
class WiFiServer : public IWiFiServer<WiFiClient> {
|
||||
private:
|
||||
int _sock;
|
||||
int _sockAccepted;
|
||||
uint16_t _port;
|
||||
uint8_t _maxClients;
|
||||
bool _active;
|
||||
bool _noDelay = false;
|
||||
|
||||
public:
|
||||
WiFiServer(uint16_t port = 80, uint8_t maxClients = 4);
|
||||
|
||||
operator bool();
|
||||
|
||||
bool begin(uint16_t port = 0, bool reuseAddr = true);
|
||||
void end();
|
||||
WiFiClient accept();
|
||||
|
||||
size_t write(const uint8_t *buffer, size_t size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void stopAll() {}
|
||||
|
||||
int setTimeout(uint32_t seconds);
|
||||
void setNoDelay(bool noDelay);
|
||||
bool getNoDelay();
|
||||
bool hasClient();
|
||||
};
|
||||
@@ -17,6 +17,7 @@ env.Prepend(
|
||||
# fmt: off
|
||||
join(API_DIR),
|
||||
join(LT_API_DIR),
|
||||
join(LT_API_DIR, "compat"),
|
||||
# fmt: on
|
||||
]
|
||||
)
|
||||
|
||||
@@ -61,6 +61,7 @@ env.Append(
|
||||
("bool", "bool"),
|
||||
# enable LwIPRxBuffer
|
||||
"LT_HAS_LWIP",
|
||||
("zalloc", "os_zalloc"),
|
||||
],
|
||||
LINKFLAGS=[
|
||||
"--specs=nosys.specs",
|
||||
@@ -170,6 +171,7 @@ sources_libs = [
|
||||
"+<" + CORE_DIR +"/libraries/WiFi/WiFiClient.cpp>",
|
||||
"+<" + CORE_DIR +"/libraries/WiFi/WiFiGeneric.cpp>",
|
||||
"+<" + CORE_DIR +"/libraries/WiFi/WiFiScan.cpp>",
|
||||
"+<" + CORE_DIR +"/libraries/WiFi/WiFiServer.cpp>",
|
||||
"+<" + CORE_DIR +"/libraries/WiFi/WiFiSTA.cpp>",
|
||||
# fmt: on
|
||||
]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <wifi_conf.h>
|
||||
|
||||
// wifi_mode is declared in atcmd_wifi.c, which is a part of the built-in trash console
|
||||
rtw_mode_t wifi_mode = RTW_MODE_STA;
|
||||
rtw_mode_t wifi_mode = RTW_MODE_NONE;
|
||||
|
||||
Reference in New Issue
Block a user