REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
native_ethernet_client.h
Go to the documentation of this file.
1#pragma once
2
3#ifdef _WIN64
4#include <winsock2.h>
5#pragma comment(lib, "ws2_32.lib")
6#else
7#include <netinet/in.h>
8#include <netinet/tcp.h>
9#include <sys/ioctl.h>
10#include <unistd.h>
11#endif
12
13#include <Arduino.h>
14#include <IPAddress.h>
15#include <stdexcept>
16
17#include <net/ethernet_client_hal.h>
18
19namespace net {
20
21class EthernetServer;
22
23class NativeEthernetClientHAL : public EthernetClientHAL {
24public:
26 :
27#ifdef _WIN64
28 client_fd(INVALID_SOCKET)
29#else
30 client_fd(-1)
31#endif
32 {
33 }
34
36 if (isConnected()) {
37 stop();
38 }
39 }
40
41 int connect(IPAddress ip, uint16_t port) override { throw std::runtime_error("not impl"); }
42
43 int connect(const char *host, uint16_t port) override { throw std::runtime_error("not impl"); }
44
45 int connectNoWait(const IPAddress &ip, uint16_t port) override { throw std::runtime_error("not impl"); }
46
47 int connectNoWait(const char *host, uint16_t port) override { throw std::runtime_error("not impl"); }
48
49 uint8_t connected() override {
50 if (!isConnected())
51 return 0;
52
53 int error = 0;
54 socklen_t len = sizeof(error);
55
56#ifdef _WIN64
57 int retval = getsockopt(client_fd, SOL_SOCKET, SO_ERROR, reinterpret_cast<char *>(&error), &len);
58#else
59 int retval = getsockopt(client_fd, SOL_SOCKET, SO_ERROR, &error, &len);
60#endif
61
62 return retval == 0 && error == 0;
63 }
64
65 explicit operator bool() override {
66#ifdef _WIN64
67 return client_fd != INVALID_SOCKET;
68#else
69 return client_fd != -1;
70#endif
71 }
72
73 void setConnectionTimeout(uint16_t timeout) override { throw std::runtime_error("not impl"); }
74
75 uint16_t connectionTimeout() const override { throw std::runtime_error("not impl"); }
76
77 void stop() override {
78 if (isConnected()) {
79#ifdef _WIN64
80 closesocket(client_fd);
81 client_fd = INVALID_SOCKET;
82#else
84 client_fd = -1;
85#endif
86 }
87 }
88
89 void close() override { stop(); }
90
91 void closeOutput() override { throw std::runtime_error("not impl"); }
92
93 void abort() override { throw std::runtime_error("not impl"); }
94
95 uint16_t localPort() override { throw std::runtime_error("not impl"); }
96
97 IPAddress remoteIP() override {
98 if (!isConnected())
99 throw std::runtime_error("not connected");
100
101 sockaddr_in addr;
102 socklen_t addr_size = sizeof(struct sockaddr_in);
103 int res = getpeername(client_fd, (struct sockaddr *)&addr, &addr_size);
104 if (res != 0) {
105 throw std::runtime_error("unable to find remote ip");
106 }
107 return {static_cast<unsigned int>(addr.sin_addr.s_addr)};
108 }
109
110 uint16_t remotePort() override {
111 if (!isConnected())
112 throw std::runtime_error("not connected");
113
114 sockaddr_in addr;
115 socklen_t addr_size = sizeof(struct sockaddr_in);
116 int res = getpeername(client_fd, (struct sockaddr *)&addr, &addr_size);
117 if (res != 0) {
118 throw std::runtime_error("unable to find remote port");
119 }
120 return addr.sin_port;
121 }
122
123 IPAddress localIP() override { throw std::runtime_error("not impl"); }
124
125 uintptr_t connectionId() override { throw std::runtime_error("not impl"); }
126
127 size_t writeFully(uint8_t b) override { return writeFully(&b, 1); }
128
129 size_t writeFully(const char *s) override { return writeFully(s, strlen(s)); }
130
131 size_t writeFully(const char *s, size_t size) override {
132 return writeFully(reinterpret_cast<const uint8_t *>(s), size * sizeof(char));
133 }
134
135 size_t writeFully(const uint8_t *buf, size_t size) override {
136 size_t write_size = write(buf, size);
137 flush();
138 return write_size;
139 }
140
141 size_t write(uint8_t b) override {
142#ifdef _WIN64
143 return send(client_fd, reinterpret_cast<const char *>(&b), 1, 0);
144#else
145 return ::write(client_fd, &b, 1);
146#endif
147 }
148
149 size_t write(const uint8_t *buf, size_t size) override {
150#ifdef _WIN64
151 return send(client_fd, reinterpret_cast<const char *>(buf), size, 0);
152#else
153 return ::write(client_fd, buf, size);
154#endif
155 }
156
157 int availableForWrite() override { throw std::runtime_error("not impl"); }
158
159 void flush() override {
160 int flag = 1;
161#ifdef _WIN64
162 setsockopt(client_fd, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char *>(&flag), sizeof(int));
163#else
164 setsockopt(client_fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int));
165#endif
166 }
167
168 int available() override {
169 if (!isConnected())
170 return 0;
171
172 unsigned long bytes_available;
173#ifdef _WIN64
174 int result = ioctlsocket(client_fd, FIONREAD, &bytes_available);
175#else
176 int result = ::ioctl(client_fd, FIONREAD, &bytes_available);
177#endif
178
179 if (result != 0)
180 return 0;
181 return static_cast<int>(bytes_available);
182 }
183
184 int read() override {
185 if (!isConnected())
186 return -1;
187
188#ifdef _WIN64
189 int res = recv(client_fd, reinterpret_cast<char *>(input_buffer), 1, 0);
190#else
191 int res = ::read(client_fd, input_buffer, 1);
192#endif
193
194 if (res <= 0)
195 return -1;
196 return input_buffer[0];
197 }
198
199 int read(uint8_t *buf, size_t size) override { throw std::runtime_error("not impl"); }
200
201 int peek() override { throw std::runtime_error("not impl"); }
202
203 void setNoDelay(bool flag) override { throw std::runtime_error("not impl"); }
204
205 bool isNoDelay() override { throw std::runtime_error("not impl"); }
206
207private:
208 bool isConnected() const {
209#ifdef _WIN64
210 return client_fd != INVALID_SOCKET;
211#else
212 return client_fd != -1;
213#endif
214 }
215
216public:
217#ifdef _WIN64
218 explicit NativeEthernetClientHAL(SOCKET client_socket)
219#else
220 explicit NativeEthernetClientHAL(int client_socket)
221#endif
222 : client_fd(client_socket) {
223 }
224
225#ifdef _WIN64
226 SOCKET client_fd;
227#else
229#endif
230
231 uint8_t input_buffer[512];
232
234};
235
236} // namespace net
size_t write(const uint8_t *buf, size_t size) override
size_t write(uint8_t b) override
int connectNoWait(const char *host, uint16_t port) override
size_t writeFully(const uint8_t *buf, size_t size) override
int connectNoWait(const IPAddress &ip, uint16_t port) override
int connect(const char *host, uint16_t port) override
void setNoDelay(bool flag) override
size_t writeFully(uint8_t b) override
size_t writeFully(const char *s, size_t size) override
uint16_t connectionTimeout() const override
int read(uint8_t *buf, size_t size) override
size_t writeFully(const char *s) override
void setConnectionTimeout(uint16_t timeout) override
int connect(IPAddress ip, uint16_t port) override
uint32_t uint32_t size
Definition flasher.cpp:63