-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGC.ino
83 lines (79 loc) · 3.07 KB
/
GC.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//check if there are any new clients
if (server.hasClient()) {
//find free/disconnected spot
int i;
for (i = 0; i < MAX_SRV_CLIENTS; i++)
if (!serverClients[i]) { // equivalent to !serverClients[i].connected()
serverClients[i] = server.available();
logger->print("New client: index ");
logger->print(i);
break;
}
//no free/disconnected spot so reject
if (i == MAX_SRV_CLIENTS) {
server.available().println("busy");
// hints: server.available() is a WiFiClient with short-term scope
// when out of scope, a WiFiClient will
// - flush() - all data will be sent
// - stop() - automatically too
logger->printf("server is busy with %d active connections\n", MAX_SRV_CLIENTS);
}
}
//check TCP clients for data
#if 1
// Incredibly, this code is faster than the bufferred one below - #4620 is needed
// loopback/3000000baud average 348KB/s
for (int i = 0; i < MAX_SRV_CLIENTS; i++)
while (serverClients[i].available() && Serial.availableForWrite() > 0) {
// working char by char is not very efficient
Serial.write(serverClients[i].read());
}
#else
// loopback/3000000baud average: 312KB/s
for (int i = 0; i < MAX_SRV_CLIENTS; i++)
while (serverClients[i].available() && Serial.availableForWrite() > 0) {
size_t maxToSerial = std::min(serverClients[i].available(), Serial.availableForWrite());
maxToSerial = std::min(maxToSerial, (size_t)STACK_PROTECTOR);
uint8_t buf[maxToSerial];
size_t tcp_got = serverClients[i].read(buf, maxToSerial);
size_t serial_sent = Serial.write(buf, tcp_got);
if (serial_sent != maxToSerial) {
logger->printf("len mismatch: available:%zd tcp-read:%zd serial-write:%zd\n", maxToSerial, tcp_got, serial_sent);
}
}
#endif
// determine maximum output size "fair TCP use"
// client.availableForWrite() returns 0 when !client.connected()
size_t maxToTcp = 0;
for (int i = 0; i < MAX_SRV_CLIENTS; i++)
if (serverClients[i]) {
size_t afw = serverClients[i].availableForWrite();
if (afw) {
if (!maxToTcp) {
maxToTcp = afw;
} else {
maxToTcp = std::min(maxToTcp, afw);
}
} else {
// warn but ignore congested clients
logger->println("one client is congested");
}
}
//check UART for data
size_t len = std::min((size_t)Serial.available(), maxToTcp);
len = std::min(len, (size_t)STACK_PROTECTOR);
if (len) {
uint8_t sbuf[len];
size_t serial_got = Serial.readBytes(sbuf, len);
// push UART data to all connected telnet clients
for (int i = 0; i < MAX_SRV_CLIENTS; i++)
// if client.availableForWrite() was 0 (congested)
// and increased since then,
// ensure write space is sufficient:
if (serverClients[i].availableForWrite() >= serial_got) {
size_t tcp_sent = serverClients[i].write(sbuf, serial_got);
if (tcp_sent != len) {
logger->printf("len mismatch: available:%zd serial-read:%zd tcp-write:%zd\n", len, serial_got, tcp_sent);
}
}
}