Skip to content

Commit 58ef04a

Browse files
committed
WiFiServer - implementation aligned with Arduino.cc with example
1 parent f6e12eb commit 58ef04a

File tree

4 files changed

+187
-11
lines changed

4 files changed

+187
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
WiFi Pager Server - server.available
3+
and print-to-all-clients example
4+
5+
The example is a simple server that echoes any incoming
6+
messages to all connected clients. Connect two or more
7+
telnet sessions to see how server.available() and
8+
server.print() work.
9+
10+
created in September 2020
11+
by Juraj Andrassy
12+
*/
13+
14+
#include <WiFi.h>
15+
16+
WiFiServer server(2323);
17+
18+
#include "arduino_secrets.h"
19+
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
20+
char ssid[] = SECRET_SSID; // your network SSID (name)
21+
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
22+
23+
void setup() {
24+
25+
Serial.begin(115200);
26+
while (!Serial);
27+
28+
Serial.print("Attempting to connect to SSID \"");
29+
Serial.print(ssid);
30+
Serial.println("\" with DHCP ...");
31+
WiFi.begin(ssid, pass);
32+
while (WiFi.status() != WL_CONNECTED) {
33+
Serial.print('.');
34+
delay(1000);
35+
}
36+
Serial.println();
37+
38+
server.begin();
39+
40+
IPAddress ip = WiFi.localIP();
41+
Serial.println();
42+
Serial.println("Connected to WiFi network.");
43+
Serial.print("To access the server, connect with Telnet client to ");
44+
Serial.print(ip);
45+
Serial.println(" 2323");
46+
}
47+
48+
void loop() {
49+
50+
WiFiClient client = server.available(); // returns first client which has data to read or a 'false' client
51+
if (client) { // client is here true only if it is connected and has data to read
52+
String s = client.readStringUntil('\n'); // read the message incoming from one of the clients
53+
s.trim(); // trim eventual \r
54+
Serial.println(s); // print the message to Serial Monitor
55+
client.print("echo: "); // this is only for the sending client
56+
server.println(s); // send the message to all connected clients
57+
server.flush(); // flush the buffers
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#define SECRET_SSID ""
2+
#define SECRET_PASS ""

libraries/WiFi/src/WiFiServer.cpp

+109-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,59 @@
2323
#undef write
2424
#undef close
2525

26+
#if !CONFIG_DISABLE_HAL_LOCKS
27+
#define WIFISERVER_MUTEX_LOCK() do {} while (xSemaphoreTake(_lock, portMAX_DELAY) != pdPASS)
28+
#define WIFISERVER_MUTEX_UNLOCK() xSemaphoreGive(_lock)
29+
#else
30+
#define WIFISERVER_MUTEX_LOCK()
31+
#define WIFISERVER_MUTEX_UNLOCK()
32+
#endif
33+
34+
WiFiServer::WiFiServer(uint16_t port, uint8_t max_clients) :
35+
sockfd(-1), _accepted_sockfd(-1), _addr(), _port(port), _max_clients(max_clients), _listening(false), _noDelay(false)
36+
#if !CONFIG_DISABLE_HAL_LOCKS
37+
, _lock(NULL)
38+
#endif
39+
{
40+
log_v("WiFiServer::WiFiServer(port=%d, ...)", port);
41+
#if !CONFIG_DISABLE_HAL_LOCKS
42+
if (_lock == NULL) {
43+
_lock = xSemaphoreCreateMutex();
44+
if (_lock == NULL) {
45+
log_e("xSemaphoreCreateMutex failed");
46+
return;
47+
}
48+
}
49+
#endif
50+
}
51+
52+
WiFiServer::WiFiServer(const IPAddress &addr, uint16_t port, uint8_t max_clients) :
53+
sockfd(-1), _accepted_sockfd(-1), _addr(addr), _port(port), _max_clients(max_clients), _listening(false), _noDelay(false)
54+
#if !CONFIG_DISABLE_HAL_LOCKS
55+
, _lock(NULL)
56+
#endif
57+
{
58+
log_v("WiFiServer::WiFiServer(addr=%s, port=%d, ...)", addr.toString().c_str(), port);
59+
#if !CONFIG_DISABLE_HAL_LOCKS
60+
if (_lock == NULL) {
61+
_lock = xSemaphoreCreateMutex();
62+
if (_lock == NULL) {
63+
log_e("xSemaphoreCreateMutex failed");
64+
return;
65+
}
66+
}
67+
#endif
68+
}
69+
70+
WiFiServer::~WiFiServer() {
71+
end();
72+
#if !CONFIG_DISABLE_HAL_LOCKS
73+
if (_lock != NULL) {
74+
vSemaphoreDelete(_lock);
75+
}
76+
#endif
77+
}
78+
2679
int WiFiServer::setTimeout(uint32_t seconds){
2780
struct timeval tv;
2881
tv.tv_sec = seconds;
@@ -33,13 +86,49 @@ int WiFiServer::setTimeout(uint32_t seconds){
3386
}
3487

3588
size_t WiFiServer::write(const uint8_t *data, size_t len){
36-
return 0;
89+
WIFISERVER_MUTEX_LOCK();
90+
static uint32_t lastCheck;
91+
uint32_t m = millis();
92+
if (m - lastCheck > 100) {
93+
lastCheck = m;
94+
acceptClients();
95+
}
96+
size_t ret = 0;
97+
if (len > 0) {
98+
for (uint8_t i = 0; i < SERVER_MAX_MONITORED_CLIENTS; i++) {
99+
if (connectedClients[i].connected()) {
100+
ret += connectedClients[i].write(data, len);
101+
}
102+
}
103+
}
104+
WIFISERVER_MUTEX_UNLOCK();
105+
return ret;
37106
}
38107

39108
void WiFiServer::stopAll(){}
40109

41-
WiFiClient WiFiServer::available(){
42-
return accept();
110+
// https://www.arduino.cc/en/Reference/WiFiServerAvailable
111+
WiFiClient WiFiServer::available() {
112+
WIFISERVER_MUTEX_LOCK();
113+
114+
acceptClients();
115+
116+
WiFiClient ret;
117+
118+
// find next client with data available
119+
for (uint8_t i = 0; i < SERVER_MAX_MONITORED_CLIENTS; i++) {
120+
if (index == SERVER_MAX_MONITORED_CLIENTS) {
121+
index = 0;
122+
}
123+
WiFiClient& client = connectedClients[index];
124+
index++;
125+
if (client.available()) {
126+
ret = client;
127+
break;
128+
}
129+
}
130+
WIFISERVER_MUTEX_UNLOCK();
131+
return ret;
43132
}
44133

45134
WiFiClient WiFiServer::accept(){
@@ -131,6 +220,14 @@ void WiFiServer::end(){
131220
#endif
132221
sockfd = -1;
133222
_listening = false;
223+
224+
WIFISERVER_MUTEX_LOCK();
225+
for (uint8_t i = 0; i < SERVER_MAX_MONITORED_CLIENTS; i++) {
226+
if (connectedClients[i]) {
227+
connectedClients[i].stop();
228+
}
229+
}
230+
WIFISERVER_MUTEX_UNLOCK();
134231
}
135232

136233
void WiFiServer::close(){
@@ -141,3 +238,12 @@ void WiFiServer::stop(){
141238
end();
142239
}
143240

241+
void WiFiServer::acceptClients() {
242+
for (uint8_t i = 0; i < SERVER_MAX_MONITORED_CLIENTS; i++) {
243+
WiFiClient& client = connectedClients[i];
244+
if (!client.connected() && !client.available()) {
245+
client = accept();
246+
}
247+
}
248+
}
249+

libraries/WiFi/src/WiFiServer.h

+17-8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
#include "WiFiClient.h"
2525
#include "IPAddress.h"
2626

27+
#ifndef SERVER_MAX_MONITORED_CLIENTS
28+
#define SERVER_MAX_MONITORED_CLIENTS CONFIG_LWIP_MAX_SOCKETS
29+
#endif
30+
2731
class WiFiServer : public Server {
2832
private:
2933
int sockfd;
@@ -33,18 +37,23 @@ class WiFiServer : public Server {
3337
uint8_t _max_clients;
3438
bool _listening;
3539
bool _noDelay = false;
40+
41+
WiFiClient connectedClients[SERVER_MAX_MONITORED_CLIENTS];
42+
uint8_t index = 0;
43+
44+
#if !CONFIG_DISABLE_HAL_LOCKS
45+
SemaphoreHandle_t _lock;
46+
#endif
47+
48+
void acceptClients();
3649

3750
public:
3851
void listenOnLocalhost(){}
3952

40-
// _addr(INADDR_ANY) is the same as _addr() ==> 0.0.0.0
41-
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) {
42-
log_v("WiFiServer::WiFiServer(port=%d, ...)", port);
43-
}
44-
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) {
45-
log_v("WiFiServer::WiFiServer(addr=%s, port=%d, ...)", addr.toString().c_str(), port);
46-
}
47-
~WiFiServer(){ end();}
53+
WiFiServer(uint16_t port=80, uint8_t max_clients=4);
54+
WiFiServer(const IPAddress& addr, uint16_t port=80, uint8_t max_clients=4);
55+
~WiFiServer();
56+
4857
WiFiClient available();
4958
WiFiClient accept();
5059
void begin(uint16_t port=0);

0 commit comments

Comments
 (0)