Skip to content

Commit 7e88a57

Browse files
fixing lwip server
1 parent 99ca0fa commit 7e88a57

File tree

7 files changed

+61
-30
lines changed

7 files changed

+61
-30
lines changed

libraries/Ethernet/src/EthernetClient.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ class EthernetClient : public lwipClient {
99
EthernetClient(struct tcp_pcb *pcb, lwipServer *server)
1010
: lwipClient(pcb, server) {
1111
}
12-
EthernetClient(lwipClient c)
12+
EthernetClient(const lwipClient &c)
1313
: lwipClient(c) {
14+
this->bindCNetIf(Ethernet);
1415
}
1516

1617
int connect(IPAddress ip, uint16_t port) {

libraries/Ethernet/src/EthernetServer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class EthernetServer: public lwipServer {
1212
}
1313

1414
EthernetClient available() {
15-
return EthernetClient(lwipServer::available());
15+
lwipClient* res = available_ptr();
16+
return res != nullptr ? EthernetClient(*res) : EthernetClient(CLIENT_NONE);
1617
}
1718
};

libraries/WiFi/src/WiFiClient.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ class WiFiClient: public lwipClient {
99
WiFiClient(struct tcp_pcb *pcb, lwipServer *server)
1010
: lwipClient(pcb, server) {
1111
}
12-
WiFiClient(lwipClient c)
12+
WiFiClient(const lwipClient &c)
1313
: lwipClient(c) {
14+
this->bindCNetIf(WiFiStation);
1415
}
1516

1617
int connect(IPAddress ip, uint16_t port) {

libraries/WiFi/src/WiFiServer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class WiFiServer: public lwipServer {
1212
}
1313

1414
WiFiClient available() {
15-
return WiFiClient(lwipServer::available());
15+
lwipClient* res = available_ptr();
16+
return res != nullptr ? WiFiClient(*res) : WiFiClient(CLIENT_NONE);
1617
}
1718
};

libraries/lwIpWrapper/src/lwipClient.cpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ lwipClient& lwipClient::operator=(lwipClient&& rhs) {
8080
}
8181

8282
lwipClient::~lwipClient() {
83-
this->stop();
83+
if(this->tcp_info->state != TCP_CLOSING) {
84+
this->stop();
85+
}
8486
}
8587

8688
int lwipClient::connect(const char* host, uint16_t port) {
@@ -231,7 +233,7 @@ err_t lwipClient::recv_callback(struct tcp_pcb* tpcb, struct pbuf* p, err_t err)
231233
return ERR_OK;
232234
}
233235
arduino::lock();
234-
if(this->tcp_info->state == TCP_CONNECTED) {
236+
if(this->tcp_info->state == TCP_CONNECTED || this->tcp_info->state == TCP_ACCEPTED) {
235237
if (this->tcp_info->pbuf_head == nullptr) {
236238
// no need to increment the references of the pbuf,
237239
// since it is already 1 and lwip shifts the control to this code
@@ -273,16 +275,11 @@ size_t lwipClient::write(const uint8_t* buffer, size_t size) {
273275
} else if(res == ERR_MEM) {
274276
// FIXME handle this: we get into this case only if the sent data cannot be put in the send queue
275277
}
276-
277-
// TODO understand if the tcp_write will send data if the buffer is not full
278-
// force send only if we filled the send buffer
279-
// if (ERR_OK != tcp_output(this->tcp_info->pcb)) {
280-
// // return 0;
281-
// break;
282-
// }
283278
} while(buffer_cursor < buffer + size);
284-
arduino::unlock();
285279

280+
tcp_output(this->tcp_info->pcb);
281+
282+
arduino::unlock();
286283
return buffer - buffer_cursor;
287284
}
288285

@@ -342,13 +339,13 @@ void lwipClient::flush() {
342339
}
343340

344341
void lwipClient::stop() {
345-
tcp_recv(this->tcp_info->pcb, nullptr);
346-
tcp_sent(this->tcp_info->pcb, nullptr);
347-
tcp_poll(this->tcp_info->pcb, nullptr, 0);
348-
tcp_err(this->tcp_info->pcb, nullptr);
349-
tcp_accept(this->tcp_info->pcb, nullptr);
350-
351342
if(this->tcp_info->pcb != nullptr) {
343+
tcp_recv(this->tcp_info->pcb, nullptr);
344+
tcp_sent(this->tcp_info->pcb, nullptr);
345+
tcp_poll(this->tcp_info->pcb, nullptr, 0);
346+
tcp_err(this->tcp_info->pcb, nullptr);
347+
tcp_accept(this->tcp_info->pcb, nullptr);
348+
352349
err_t err = tcp_close(this->tcp_info->pcb);
353350
this->tcp_info->state = TCP_CLOSING;
354351

@@ -362,6 +359,12 @@ void lwipClient::stop() {
362359
// if(tcp->p != nullptr) {
363360
// pbuf_free(tcp->p); // FIXME it happens that a pbuf, with ref == 0 is added for some reason
364361
// }
362+
if(this->tcp_info->server != nullptr) {
363+
// need to first make the server point to nullptr, then remove the client, can cause infinite recursion
364+
auto server = this->tcp_info->server;
365+
this->tcp_info->server = nullptr;
366+
server->remove(this);
367+
}
365368
}
366369

367370
uint8_t lwipClient::connected() {

libraries/lwIpWrapper/src/lwipServer.cpp

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ extern "C" {
55
#include "CNetIf.h"
66
#include "lwipClient.h"
77
#include "lwipServer.h"
8+
#include "utils.h"
89

910
err_t tcp_accept_callback(void* arg, struct tcp_pcb* newpcb, err_t err);
1011

@@ -74,9 +75,12 @@ void lwipServer::begin(uint16_t port)
7475
// }
7576

7677
void lwipServer::remove(lwipClient* client) {
78+
arduino::lock();
79+
7780
bool found = false;
7881
for (int i=0; i < size; i++) {
7982
if(found) {
83+
// we move the client to delete to the end of the array, then we remove it
8084
clients[i-1] = clients[i];
8185
} else if(*client == *clients[i]) {
8286
found = true;
@@ -85,25 +89,41 @@ void lwipServer::remove(lwipClient* client) {
8589

8690
delete clients[--size];
8791
clients[size] = nullptr;
92+
93+
arduino::unlock();
8894
}
8995

90-
void lwipServer::accept(struct tcp_pcb* new_client) {
96+
bool lwipServer::accept(struct tcp_pcb* new_client) {
97+
bool res = false;
9198
// this->clean();
92-
99+
arduino::lock();
93100
if(size < MAX_CLIENT-1) {
94101
clients[size] = new lwipClient(new_client, this);
95102
size++;
96103
clients_available++;
104+
res = true;
97105
}
106+
arduino::unlock();
107+
108+
return res;
98109
}
99110

100111
lwipClient lwipServer::available()
101112
{
113+
lwipClient* res = available_ptr();
114+
return res != nullptr ? *res : CLIENT_NONE;
115+
}
116+
117+
lwipClient* lwipServer::available_ptr()
118+
{
119+
lwipClient* res=nullptr;
120+
arduino::lock();
102121
if(size > 0 && clients_available>0) {
103-
return *clients[size-clients_available--]; // TODO verify index
104-
} else {
105-
return CLIENT_NONE;
122+
res = clients[size-clients_available--]; // TODO verify index
106123
}
124+
arduino::unlock();
125+
126+
return res;
107127
}
108128

109129
size_t lwipServer::write(uint8_t b)
@@ -112,28 +132,30 @@ size_t lwipServer::write(uint8_t b)
112132
}
113133

114134
size_t lwipServer::write(const uint8_t* buffer, size_t size) {
135+
arduino::lock();
115136
size_t written=0;
116137
// this->clean();
117138

118139
for (int i = 0; i < MAX_CLIENT; i++) {
119140
written += clients[i]->write(buffer, size);
120141
}
142+
arduino::unlock();
121143

122144
return written;
123145
}
124146

125147
err_t tcp_accept_callback(void* arg, struct tcp_pcb* newpcb, err_t err) {
148+
arduino::lock();
126149
lwipServer* server = (lwipServer*) arg;
127-
err_t ret_err;
150+
err_t ret_err = ERR_OK;
128151

129152
/* set priority for the newly accepted tcp connection newpcb */
130153
tcp_setprio(newpcb, TCP_PRIO_MIN);
131154

132-
if ((arg != NULL) && (ERR_OK == err)) {
133-
server->accept(newpcb);
134-
} else {
155+
if ((arg == NULL) || (ERR_OK != err) || !server->accept(newpcb)) {
135156
tcp_close(newpcb);
136157
ret_err = ERR_ARG;
137158
}
159+
arduino::unlock();
138160
return ret_err;
139161
}

libraries/lwIpWrapper/src/lwipServer.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ class lwipServer: public Server {
3131
* - when a client connection is closed (by calling stop on it or delete on the client)
3232
* the server is notified and the remove() method is called thus the client is removed from the server list.
3333
*/
34-
void accept(struct tcp_pcb* new_client);
34+
bool accept(struct tcp_pcb* new_client);
3535
// void clean();
3636
void remove(lwipClient* client);
3737

38+
lwipClient* available_ptr();
39+
3840
uint16_t _port;
3941
const IPAddress &listen_address;
4042
tcp_pcb* server_pcb;

0 commit comments

Comments
 (0)