Skip to content

WiFiServer - implementation aligned with Arduino.cc. With example. (breaking change) #9028

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
59 changes: 59 additions & 0 deletions libraries/WiFi/examples/WiFiPagerServer/WiFiPagerServer.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
WiFi Pager Server - server.available
and print-to-all-clients example

The example is a simple server that echoes any incoming
messages to all connected clients. Connect two or more
telnet sessions to see how server.available() and
server.print() work.

created in September 2020
by Juraj Andrassy
*/

#include <WiFi.h>

WiFiServer server(2323);

#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)

void setup() {

Serial.begin(115200);
while (!Serial);

Serial.print("Attempting to connect to SSID \"");
Serial.print(ssid);
Serial.println("\" with DHCP ...");
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
Serial.println();

server.begin();

IPAddress ip = WiFi.localIP();
Serial.println();
Serial.println("Connected to WiFi network.");
Serial.print("To access the server, connect with Telnet client to ");
Serial.print(ip);
Serial.println(" 2323");
}

void loop() {

WiFiClient client = server.available(); // returns first client which has data to read or a 'false' client
if (client) { // client is here true only if it is connected and has data to read
String s = client.readStringUntil('\n'); // read the message incoming from one of the clients
s.trim(); // trim eventual \r
Serial.println(s); // print the message to Serial Monitor
client.print("echo: "); // this is only for the sending client
server.println(s); // send the message to all connected clients
server.flush(); // flush the buffers
}
}
2 changes: 2 additions & 0 deletions libraries/WiFi/examples/WiFiPagerServer/arduino_secrets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#define SECRET_SSID ""
#define SECRET_PASS ""
113 changes: 110 additions & 3 deletions libraries/WiFi/src/WiFiServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,59 @@
#undef write
#undef close

#if !CONFIG_DISABLE_HAL_LOCKS
#define WIFISERVER_MUTEX_LOCK() do {} while (xSemaphoreTake(_lock, portMAX_DELAY) != pdPASS)
#define WIFISERVER_MUTEX_UNLOCK() xSemaphoreGive(_lock)
#else
#define WIFISERVER_MUTEX_LOCK()
#define WIFISERVER_MUTEX_UNLOCK()
#endif

WiFiServer::WiFiServer(uint16_t port, uint8_t max_clients) :
sockfd(-1), _accepted_sockfd(-1), _addr(), _port(port), _max_clients(max_clients), _listening(false), _noDelay(false)
#if !CONFIG_DISABLE_HAL_LOCKS
, _lock(NULL)
#endif
{
log_v("WiFiServer::WiFiServer(port=%d, ...)", port);
#if !CONFIG_DISABLE_HAL_LOCKS
if (_lock == NULL) {
_lock = xSemaphoreCreateMutex();
if (_lock == NULL) {
log_e("xSemaphoreCreateMutex failed");
return;
}
}
#endif
}

WiFiServer::WiFiServer(const IPAddress &addr, uint16_t port, uint8_t max_clients) :
sockfd(-1), _accepted_sockfd(-1), _addr(addr), _port(port), _max_clients(max_clients), _listening(false), _noDelay(false)
#if !CONFIG_DISABLE_HAL_LOCKS
, _lock(NULL)
#endif
{
log_v("WiFiServer::WiFiServer(addr=%s, port=%d, ...)", addr.toString().c_str(), port);
#if !CONFIG_DISABLE_HAL_LOCKS
if (_lock == NULL) {
_lock = xSemaphoreCreateMutex();
if (_lock == NULL) {
log_e("xSemaphoreCreateMutex failed");
return;
}
}
#endif
}

WiFiServer::~WiFiServer() {
end();
#if !CONFIG_DISABLE_HAL_LOCKS
if (_lock != NULL) {
vSemaphoreDelete(_lock);
}
#endif
}

int WiFiServer::setTimeout(uint32_t seconds){
struct timeval tv;
tv.tv_sec = seconds;
Expand All @@ -33,13 +86,49 @@ int WiFiServer::setTimeout(uint32_t seconds){
}

size_t WiFiServer::write(const uint8_t *data, size_t len){
return 0;
WIFISERVER_MUTEX_LOCK();
static uint32_t lastCheck;
uint32_t m = millis();
if (m - lastCheck > 100) {
lastCheck = m;
acceptClients();
}
size_t ret = 0;
if (len > 0) {
for (uint8_t i = 0; i < SERVER_MAX_MONITORED_CLIENTS; i++) {
if (connectedClients[i].connected()) {
ret += connectedClients[i].write(data, len);
}
}
}
WIFISERVER_MUTEX_UNLOCK();
return ret;
}

void WiFiServer::stopAll(){}

WiFiClient WiFiServer::available(){
return accept();
// https://www.arduino.cc/en/Reference/WiFiServerAvailable
WiFiClient WiFiServer::available() {
WIFISERVER_MUTEX_LOCK();

acceptClients();

WiFiClient ret;

// find next client with data available
for (uint8_t i = 0; i < SERVER_MAX_MONITORED_CLIENTS; i++) {
if (index == SERVER_MAX_MONITORED_CLIENTS) {
index = 0;
}
WiFiClient& client = connectedClients[index];
index++;
if (client.available()) {
ret = client;
break;
}
}
WIFISERVER_MUTEX_UNLOCK();
return ret;
}

WiFiClient WiFiServer::accept(){
Expand Down Expand Up @@ -138,6 +227,14 @@ void WiFiServer::end(){
#endif
sockfd = -1;
_listening = false;

WIFISERVER_MUTEX_LOCK();
for (uint8_t i = 0; i < SERVER_MAX_MONITORED_CLIENTS; i++) {
if (connectedClients[i]) {
connectedClients[i].stop();
}
}
WIFISERVER_MUTEX_UNLOCK();
}

void WiFiServer::close(){
Expand All @@ -147,3 +244,13 @@ void WiFiServer::close(){
void WiFiServer::stop(){
end();
}

void WiFiServer::acceptClients() {
for (uint8_t i = 0; i < SERVER_MAX_MONITORED_CLIENTS; i++) {
WiFiClient& client = connectedClients[i];
if (!client.connected() && !client.available()) {
client = accept();
}
}
}

24 changes: 17 additions & 7 deletions libraries/WiFi/src/WiFiServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
#include "WiFiClient.h"
#include "IPAddress.h"

#ifndef SERVER_MAX_MONITORED_CLIENTS
#define SERVER_MAX_MONITORED_CLIENTS CONFIG_LWIP_MAX_SOCKETS
#endif

class WiFiServer : public Server {
private:
int sockfd;
Expand All @@ -33,17 +37,23 @@ class WiFiServer : public Server {
uint8_t _max_clients;
bool _listening;
bool _noDelay = false;

WiFiClient connectedClients[SERVER_MAX_MONITORED_CLIENTS];
uint8_t index = 0;

#if !CONFIG_DISABLE_HAL_LOCKS
SemaphoreHandle_t _lock;
#endif

void acceptClients();

public:
void listenOnLocalhost(){}

WiFiServer(uint16_t port=80, uint8_t max_clients=4):sockfd(-1),_accepted_sockfd(-1),_addr(),_port(port),_max_clients(max_clients),_listening(false),_noDelay(false) {
log_v("WiFiServer::WiFiServer(port=%d, ...)", port);
}
WiFiServer(const IPAddress& addr, uint16_t port=80, uint8_t max_clients=4):sockfd(-1),_accepted_sockfd(-1),_addr(addr),_port(port),_max_clients(max_clients),_listening(false),_noDelay(false) {
log_v("WiFiServer::WiFiServer(addr=%s, port=%d, ...)", addr.toString().c_str(), port);
}
~WiFiServer(){ end();}
WiFiServer(uint16_t port=80, uint8_t max_clients=4);
WiFiServer(const IPAddress& addr, uint16_t port=80, uint8_t max_clients=4);
~WiFiServer();

WiFiClient available();
WiFiClient accept();
void begin(uint16_t port=0);
Expand Down