Skip to content

Commit 423c040

Browse files
authored
Async support (#16)
* Added set/getNoDelay() and hasClient() for ESPAsyncWebServer compat * Added write(adr, len) for ArduinoECCX08 * Added getMode() and mode() for better ESP32 compatibility * Added an Apple-compatible implementation of defaultInterface() using sysctl(), since MacOS does not have /proc Also fixed a problem in the /proc implementation, which left a dangling open file descriptor.
1 parent a707b3f commit 423c040

File tree

5 files changed

+86
-0
lines changed

5 files changed

+86
-0
lines changed

ArduinoCore-Linux/cores/arduino/EthernetServer.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class EthernetServer : public Server {
3939
struct sockaddr_in server_addr;
4040
int _status = wl_status_t::WL_DISCONNECTED;
4141
bool is_blocking = false;
42+
bool _noDelay = false;
43+
4244
static std::vector<EthernetServer*>& active_servers() {
4345
static std::vector<EthernetServer*> servers;
4446
return servers;
@@ -102,6 +104,19 @@ class EthernetServer : public Server {
102104
}
103105
int status() { return _status; }
104106

107+
// The following are for compatibility with ESP32 WiFiServer
108+
// get/setNoDelay maintain the state variable, but otherwise
109+
// have no effect on the code.
110+
void setNoDelay(bool nodelay) { _noDelay = nodelay; }
111+
bool getNoDelay() { return _noDelay; }
112+
bool hasClient() {
113+
if (server_fd <= 0) return false;
114+
struct pollfd pfd;
115+
pfd.fd = server_fd;
116+
pfd.events = POLLIN;
117+
return ::poll(&pfd, 1, 0) > 0 && (pfd.revents & POLLIN);
118+
}
119+
105120
using Print::write;
106121

107122
protected:
@@ -149,6 +164,8 @@ class EthernetServer : public Server {
149164
return false;
150165
}
151166

167+
_noDelay = false;
168+
152169
// Add to active servers list for signal handling
153170
active_servers().push_back(this);
154171
_status = wl_status_t::WL_CONNECTED;

ArduinoCore-Linux/cores/arduino/I2CWrapper.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,17 @@ void I2CWrapper::onReceive(void (*)(int)) {}
9898

9999
void I2CWrapper::onRequest(void (*)(void)) {}
100100

101+
size_t I2CWrapper::write(const uint8_t* data, size_t len) {
102+
int cnt = len;
103+
while (cnt) {
104+
if (!write(*data++)) {
105+
return len - cnt;
106+
}
107+
--cnt;
108+
}
109+
return len;
110+
}
111+
101112
size_t I2CWrapper::write(uint8_t data) {
102113
HardwareI2C* i2c = getI2C();
103114
if (i2c != nullptr) {

ArduinoCore-Linux/cores/arduino/I2CWrapper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class I2CWrapper : public HardwareI2C {
6666
void onReceive(void (*)(int));
6767
void onRequest(void (*)(void));
6868
size_t write(uint8_t);
69+
size_t write(const uint8_t *, size_t);
6970
int available();
7071
int read();
7172
int peek();

ArduinoCore-Linux/cores/arduino/SocketImpl.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
#include <sys/socket.h>
3131
#include <sys/types.h>
3232
#include <unistd.h>
33+
#ifdef __APPLE__
34+
#include <net/route.h>
35+
#include <sys/sysctl.h>
36+
#endif
3337

3438
#include <cstring>
3539

@@ -138,11 +142,55 @@ void SocketImpl::close() {
138142
::close(sock);
139143
}
140144

145+
#ifndef __APPLE__
146+
// The sysctl() method of getting the routing table information also
147+
// works in Linux, but is deprecated there.
148+
static char *defaultInterface() {
149+
int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY};
150+
size_t needed = 0;
151+
152+
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0 || needed == 0)
153+
return nullptr;
154+
155+
char *buf = (char *)malloc(needed);
156+
if (!buf) return nullptr;
157+
158+
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
159+
free(buf);
160+
return nullptr;
161+
}
162+
163+
static char ifname[IF_NAMESIZE];
164+
char *result = nullptr;
165+
166+
for (char *p = buf; p < buf + needed;) {
167+
struct rt_msghdr *rtm = (struct rt_msghdr *)p;
168+
struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
169+
if (sa->sa_family == AF_INET) {
170+
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
171+
if (sin->sin_addr.s_addr == INADDR_ANY) {
172+
if (if_indextoname(rtm->rtm_index, ifname) != nullptr) {
173+
Logger.info("Default network interface is ", ifname);
174+
result = ifname;
175+
}
176+
break;
177+
}
178+
}
179+
p += rtm->rtm_msglen;
180+
}
181+
182+
free(buf);
183+
return result;
184+
}
185+
#else
141186
char *defaultInterface() {
142187
FILE *f;
143188
char line[100], *p, *c;
144189

145190
f = fopen("/proc/net/route", "r");
191+
if (!f) {
192+
return nullptr;
193+
}
146194

147195
while (fgets(line, 100, f)) {
148196
p = strtok(line, " \t");
@@ -153,12 +201,15 @@ char *defaultInterface() {
153201
static char defaultInterface[20];
154202
strcpy(defaultInterface, p);
155203
Logger.info("Default network interface is ", p);
204+
fclose(f);
156205
return defaultInterface;
157206
}
158207
}
159208
}
209+
fclose(f);
160210
return nullptr;
161211
}
212+
#endif
162213

163214
// determines the IP Adress
164215
const char *SocketImpl::getIPAddress() {

ArduinoCore-Linux/cores/arduino/WiFi.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
namespace arduino {
3333

34+
typedef enum { WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3 } WiFiMode_t; // For ESP compatibility
35+
3436
enum wifi_ps_type_t { WIFI_PS_NONE, WIFI_PS_MIN_MODEM, WIFI_PS_MAX_MODEM };
3537

3638
class WifiMock {
@@ -56,6 +58,10 @@ class WifiMock {
5658

5759
void setClientInsecure() {}
5860

61+
// WIFI_STA is the best approximation to interface enabled
62+
void mode(WiFiMode_t m);
63+
WiFiMode_t getMode() { return WIFI_STA; };
64+
5965
protected:
6066
IPAddress adress;
6167
int mac = 0;

0 commit comments

Comments
 (0)