TinyPPP
PPP networking over any Arduino Stream
Loading...
Searching...
No Matches
PPPSockets.h
Go to the documentation of this file.
1#pragma once
7#include <Client.h>
8#include <Server.h>
9#include <Udp.h>
10
11#include "IPStack.h"
12#include "PPPEngine.h"
13
14#ifndef TINYPPP_TIMEOUT
15#define TINYPPP_TIMEOUT 5000
16#endif
17
18namespace tinyppp {
19
25class PPPClient : public Client {
26 public:
28 PPPClient() = default;
33 : _stack(stack), _sock(sock), _gen(stack->tcpGen(sock)) {}
34
36 int connect(IPAddress ip, uint16_t port) override {
37 if (stack() == nullptr) return 0;
38 if (valid()) stop();
39 _sock = stack()->tcpConnect(toIp4(ip[0], ip[1], ip[2], ip[3]),
40 port, _timeout);
41 if (_sock < 0) return 0;
42 _gen = stack()->tcpGen(_sock);
43 return 1;
44 }
45
47 int connect(const char *host, uint16_t port) override {
48 if (stack() == nullptr) return 0;
50 if (!stack()->hostByName(host, ip, _timeout)) return 0;
51 return connect(ip, port);
52 }
53
55 size_t write(uint8_t b) override { return write(&b, 1); }
57 size_t write(const uint8_t *buf, size_t size) override {
58 if (!valid()) return 0;
59 size_t n = stack()->tcpWrite(_sock, buf, size, _timeout);
60 if (n < size) setWriteError();
61 return n;
62 }
63 using Print::write;
64
66 int available() override {
67 return valid() ? stack()->tcpAvailable(_sock) : 0;
68 }
69
71 int read() override {
72 uint8_t b;
73 return read(&b, 1) == 1 ? b : -1;
74 }
75
77 int read(uint8_t *buf, size_t size) override {
78 if (!valid()) return -1;
79 int n = stack()->tcpRead(_sock, buf, size);
80 return n > 0 ? n : -1;
81 }
82
84 int peek() override { return valid() ? stack()->tcpPeek(_sock) : -1; }
85
87 void flush() override {
88 if (valid()) stack()->tcpFlush(_sock, _timeout);
89 }
90
92 void stop() override {
93 if (valid()) stack()->tcpClose(_sock, 1000);
94 _sock = -1;
95 }
96
98 uint8_t connected() override {
99 if (!valid()) return 0;
100 if (stack()->tcpAvailable(_sock) > 0) return 1;
102 }
103
105 operator bool() override { return valid(); }
106
108 bool operator==(const PPPClient &other) const {
109 return _sock == other._sock && _gen == other._gen;
110 }
112 bool operator!=(const PPPClient &other) const { return !(*this == other); }
113
116 return valid() ? toIPAddress(stack()->tcpRemoteIP(_sock))
117 : IPAddress(0, 0, 0, 0);
118 }
121 return valid() ? stack()->tcpRemotePort(_sock) : 0;
122 }
124 uint16_t localPort() { return valid() ? stack()->tcpLocalPort(_sock) : 0; }
125
128
129 protected:
130 IPStack *_stack = nullptr;
131 int _sock = -1;
134
135 IPStack *stack() const {
136 return _stack ? _stack : IPStack::current();
137 }
138 bool valid() const {
139 return _sock >= 0 && stack() != nullptr && stack()->tcpValid(_sock, _gen);
140 }
141};
142
144class PPPServer : public Server {
145 public:
147 explicit PPPServer(uint16_t port = 80) : _port(port) {}
151
153 void begin() override {
154 if (stack()) _listening = stack()->tcpListen(_port);
155 }
158 end();
159 _port = port;
160 begin();
161 }
162
164 void end() {
165 if (stack() && _listening) stack()->tcpUnlisten(_port);
166 _listening = false;
167 }
168
171 int s = stack() ? stack()->tcpAccept(_port, false) : -1;
172 return s < 0 ? PPPClient() : PPPClient(stack(), s);
173 }
174
177 int s = stack() ? stack()->tcpAccept(_port, true) : -1;
178 return s < 0 ? PPPClient() : PPPClient(stack(), s);
179 }
180
182 size_t write(uint8_t b) override { return write(&b, 1); }
184 size_t write(const uint8_t *buf, size_t size) override {
185 return stack() ? stack()->tcpWriteAll(_port, buf, size, TINYPPP_TIMEOUT)
186 : 0;
187 }
188 using Print::write;
189
191 operator bool() { return _listening; }
193 uint16_t port() const { return _port; }
194
195 protected:
197 IPStack *_stack = nullptr;
198 bool _listening = false;
199
200 IPStack *stack() const {
201 return _stack ? _stack : IPStack::current();
202 }
203};
204
206class PPPUDP : public UDP {
207 public:
209 PPPUDP() = default;
211 explicit PPPUDP(IPStack &stack) : _stack(&stack) {}
212 ~PPPUDP() { stop(); }
213 PPPUDP(const PPPUDP &) = delete;
214 PPPUDP &operator=(const PPPUDP &) = delete;
215
217 uint8_t begin(uint16_t port) override {
218 stop();
219 if (stack() == nullptr) return 0;
220 _sock = stack()->udpOpen(port);
221 return _sock >= 0;
222 }
223
225 void stop() override {
226 if (_sock >= 0 && stack()) stack()->udpClose(_sock);
227 _sock = -1;
228 _txLen = 0;
229 }
230
232 int beginPacket(IPAddress ip, uint16_t port) override {
233 if (_sock < 0 && !begin(0)) return 0;
234 _txIP = ip;
235 _txPort = port;
236 _txLen = 0;
237 _txOverflow = false;
238 return 1;
239 }
240
242 int beginPacket(const char *host, uint16_t port) override {
243 if (stack() == nullptr) return 0;
245 if (!stack()->hostByName(host, ip)) return 0;
246 return beginPacket(ip, port);
247 }
248
250 int endPacket() override {
251 if (_sock < 0 || _txOverflow) return 0;
252 bool ok = stack()->udpSend(
253 _sock, toIp4(_txIP[0], _txIP[1], _txIP[2], _txIP[3]), _txPort,
254 _tx, _txLen);
255 _txLen = 0;
256 return ok;
257 }
258
260 size_t write(uint8_t b) override { return write(&b, 1); }
262 size_t write(const uint8_t *buf, size_t size) override {
263 if (_txLen + size > sizeof(_tx)) {
264 _txOverflow = true;
265 size = sizeof(_tx) - _txLen;
266 }
267 memcpy(_tx + _txLen, buf, size);
268 _txLen += size;
269 return size;
270 }
271 using Print::write;
272
274 int parsePacket() override {
275 if (_sock < 0) return 0;
276 ip4_t ip = 0;
277 int n = stack()->udpParsePacket(_sock, ip, _rxPort);
278 if (n > 0 || stack()->udpAvailable(_sock) > 0) _rxIP = toIPAddress(ip);
279 return n;
280 }
281
283 int available() override {
284 return _sock < 0 ? 0 : stack()->udpAvailable(_sock);
285 }
286
288 int read() override {
289 uint8_t b;
290 return read(&b, 1) == 1 ? b : -1;
291 }
293 int read(unsigned char *buf, size_t len) override {
294 if (_sock < 0) return -1;
295 int n = stack()->udpRead(_sock, buf, len);
296 return n > 0 ? n : -1;
297 }
299 int read(char *buf, size_t len) override {
300 return read((unsigned char *)buf, len);
301 }
302
304 int peek() override { return _sock < 0 ? -1 : stack()->udpPeek(_sock); }
305
307 void flush() override {
308 if (_sock >= 0) stack()->udpDiscard(_sock);
309 }
310
312 IPAddress remoteIP() override { return _rxIP; }
314 uint16_t remotePort() override { return _rxPort; }
316 uint16_t localPort() { return _sock < 0 ? 0 : stack()->udpLocalPort(_sock); }
317
318 protected:
319 IPStack *_stack = nullptr;
320 int _sock = -1;
325 size_t _txLen = 0;
326 bool _txOverflow = false;
328
329 IPStack *stack() const {
330 return _stack ? _stack : IPStack::current();
331 }
332};
333
334} // namespace tinyppp
#define TINYPPP_UDP_TX_BUFFER
Definition IPStack.h:47
#define TINYPPP_TIMEOUT
Definition PPPSockets.h:15
Minimal IPv4 stack (ICMP echo, UDP, TCP, DNS resolver) for platforms without lwIP.
Definition IPStack.h:195
bool udpSend(int s, ip4_t ip, uint16_t port, const uint8_t *data, size_t len)
Sends a datagram.
Definition IPStack.h:478
int tcpRead(int s, uint8_t *data, size_t len)
Reads up to len received bytes from socket s.
Definition IPStack.h:316
uint16_t udpLocalPort(int s) const
Local port of UDP socket s.
Definition IPStack.h:475
int tcpPeek(int s)
Next received byte of socket s without removing it (-1 if none)
Definition IPStack.h:310
bool tcpListen(uint16_t port)
Starts listening on a port.
Definition IPStack.h:396
uint16_t tcpLocalPort(int s) const
Local port of socket s.
Definition IPStack.h:297
int udpOpen(uint16_t port)
Opens a UDP socket on the port (0: ephemeral): returns it or -1.
Definition IPStack.h:449
int udpAvailable(int s) const
Unread bytes of the current datagram.
Definition IPStack.h:500
static IPStack *& current()
The stack used by sockets that were created without an explicit stack.
Definition IPStack.h:215
int udpPeek(int s) const
Next byte of the current datagram without removing it (-1 if none)
Definition IPStack.h:512
void udpDiscard(int s)
Discards the rest of the current datagram.
Definition IPStack.h:517
bool tcpValid(int s, uint8_t gen) const
true if socket s is open and still has the generation gen
Definition IPStack.h:288
int tcpConnect(ip4_t ip, uint16_t port, uint32_t timeoutMs)
Opens a connection: returns the socket number or -1.
Definition IPStack.h:259
int udpParsePacket(int s, ip4_t &ip, uint16_t &port)
Moves to the next datagram: returns its size (0 if none)
Definition IPStack.h:485
int tcpAvailable(int s)
Number of received bytes that can be read from socket s.
Definition IPStack.h:304
int udpRead(int s, uint8_t *data, size_t len)
Reads from the current datagram.
Definition IPStack.h:503
uint16_t tcpRemotePort(int s) const
Remote port of socket s.
Definition IPStack.h:299
uint8_t tcpGen(int s) const
Generation of socket s: changes each time the socket is reused.
Definition IPStack.h:293
void tcpUnlisten(uint16_t port)
Stops listening on a port.
Definition IPStack.h:409
size_t tcpWriteAll(uint16_t port, const uint8_t *data, size_t len, uint32_t timeoutMs)
Sends data to all connected clients of a server port.
Definition IPStack.h:434
TCPState tcpState(int s) const
Connection state of socket s.
Definition IPStack.h:295
size_t tcpWrite(int s, const uint8_t *data, size_t len, uint32_t timeoutMs)
Queues data for sending (waits for buffer space up to timeoutMs)
Definition IPStack.h:325
void tcpFlush(int s, uint32_t timeoutMs)
Waits until all queued data was acknowledged.
Definition IPStack.h:347
int tcpAccept(uint16_t port, bool withData)
Definition IPStack.h:416
void udpClose(int s)
Closes UDP socket s.
Definition IPStack.h:468
void tcpClose(int s, uint32_t timeoutMs)
Definition IPStack.h:359
TCP client over PPP: used like WiFiClient or EthernetClient.
Definition PPPSockets.h:25
void flush() override
Waits until all written data was acknowledged by the peer.
Definition PPPSockets.h:87
int read(uint8_t *buf, size_t size) override
Reads up to size bytes: returns the number read or -1.
Definition PPPSockets.h:77
IPAddress remoteIP()
Address of the peer.
Definition PPPSockets.h:115
int _sock
Definition PPPSockets.h:131
IPStack * _stack
Definition PPPSockets.h:130
bool valid() const
Definition PPPSockets.h:138
int connect(const char *host, uint16_t port) override
Resolves the host via DNS and connects: returns 1 on success.
Definition PPPSockets.h:47
uint16_t remotePort()
Port of the peer.
Definition PPPSockets.h:120
int peek() override
Next byte without removing it (-1 if none)
Definition PPPSockets.h:84
size_t write(uint8_t b) override
Sends one byte.
Definition PPPSockets.h:55
int available() override
Number of received bytes that can be read.
Definition PPPSockets.h:66
PPPClient(IPStack *stack, int sock)
Client for an existing socket (used by PPPServer)
Definition PPPSockets.h:32
bool operator!=(const PPPClient &other) const
true if they refer to different connections
Definition PPPSockets.h:112
bool operator==(const PPPClient &other) const
true if both refer to the same connection
Definition PPPSockets.h:108
IPStack * stack() const
Definition PPPSockets.h:135
void stop() override
Closes the connection.
Definition PPPSockets.h:92
int connect(IPAddress ip, uint16_t port) override
Connects to the address and port: returns 1 on success.
Definition PPPSockets.h:36
uint32_t _timeout
Definition PPPSockets.h:133
PPPClient()=default
Client on the default stack (the first TinyPPP instance)
void setConnectionTimeout(uint32_t ms)
Timeout in ms for connect, write and flush.
Definition PPPSockets.h:127
int read() override
Reads one byte (-1 if none available)
Definition PPPSockets.h:71
uint16_t localPort()
Our port.
Definition PPPSockets.h:124
uint8_t connected() override
true while connected or while received data is available
Definition PPPSockets.h:98
uint8_t _gen
Definition PPPSockets.h:132
PPPClient(IPStack &stack)
Client on the indicated stack.
Definition PPPSockets.h:30
size_t write(const uint8_t *buf, size_t size) override
Sends data (waits while the send buffer is full)
Definition PPPSockets.h:57
TCP server over PPP: used like WiFiServer or EthernetServer.
Definition PPPSockets.h:144
IPStack * _stack
Definition PPPSockets.h:197
uint16_t port() const
The server port.
Definition PPPSockets.h:193
PPPClient accept()
Returns a new connection (or an invalid client)
Definition PPPSockets.h:170
size_t write(uint8_t b) override
Writes one byte to all connected clients.
Definition PPPSockets.h:182
void begin() override
Starts listening.
Definition PPPSockets.h:153
bool _listening
Definition PPPSockets.h:198
uint16_t _port
Definition PPPSockets.h:196
void begin(uint16_t port)
Starts listening on the indicated port.
Definition PPPSockets.h:157
IPStack * stack() const
Definition PPPSockets.h:200
void end()
Stops listening (open connections stay open)
Definition PPPSockets.h:164
PPPServer(uint16_t port, IPStack &stack)
Server on the indicated stack.
Definition PPPSockets.h:149
PPPServer(uint16_t port=80)
Server on the default stack (the first TinyPPP instance)
Definition PPPSockets.h:147
size_t write(const uint8_t *buf, size_t size) override
Writes data to all connected clients.
Definition PPPSockets.h:184
PPPClient available()
Returns a connection that has data available (or an invalid client)
Definition PPPSockets.h:176
UDP socket over PPP: used like WiFiUDP or EthernetUDP.
Definition PPPSockets.h:206
uint8_t _tx[576]
Definition PPPSockets.h:327
void flush() override
Discards the rest of the current datagram.
Definition PPPSockets.h:307
IPAddress _txIP
Definition PPPSockets.h:323
int endPacket() override
Sends the datagram: returns 1 on success.
Definition PPPSockets.h:250
IPAddress _rxIP
Definition PPPSockets.h:321
int _sock
Definition PPPSockets.h:320
IPStack * _stack
Definition PPPSockets.h:319
int read(char *buf, size_t len) override
Reads from the current datagram: returns the number read or -1.
Definition PPPSockets.h:299
int peek() override
Next byte of the current datagram without removing it (-1 if none)
Definition PPPSockets.h:304
int beginPacket(const char *host, uint16_t port) override
Starts a datagram to the host (resolved via DNS) and port.
Definition PPPSockets.h:242
size_t write(uint8_t b) override
Adds one byte to the datagram.
Definition PPPSockets.h:260
bool _txOverflow
Definition PPPSockets.h:326
int available() override
Unread bytes of the current datagram.
Definition PPPSockets.h:283
size_t _txLen
Definition PPPSockets.h:325
uint16_t _rxPort
Definition PPPSockets.h:322
uint16_t remotePort() override
Sender port of the current datagram.
Definition PPPSockets.h:314
int read(unsigned char *buf, size_t len) override
Reads from the current datagram: returns the number read or -1.
Definition PPPSockets.h:293
PPPUDP & operator=(const PPPUDP &)=delete
PPPUDP()=default
UDP on the default stack (the first TinyPPP instance)
IPAddress remoteIP() override
Sender address of the current datagram.
Definition PPPSockets.h:312
IPStack * stack() const
Definition PPPSockets.h:329
~PPPUDP()
Definition PPPSockets.h:212
void stop() override
Closes the socket.
Definition PPPSockets.h:225
int beginPacket(IPAddress ip, uint16_t port) override
Starts a datagram to the address and port.
Definition PPPSockets.h:232
PPPUDP(const PPPUDP &)=delete
int read() override
Reads one byte of the current datagram (-1 if none)
Definition PPPSockets.h:288
int parsePacket() override
Moves to the next received datagram: returns its size (0 if none)
Definition PPPSockets.h:274
uint16_t _txPort
Definition PPPSockets.h:324
uint16_t localPort()
Our port.
Definition PPPSockets.h:316
PPPUDP(IPStack &stack)
UDP on the indicated stack.
Definition PPPSockets.h:211
uint8_t begin(uint16_t port) override
Opens the socket on the port (0: any port): returns 1 on success.
Definition PPPSockets.h:217
size_t write(const uint8_t *buf, size_t size) override
Adds data to the datagram (max TINYPPP_UDP_TX_BUFFER bytes)
Definition PPPSockets.h:262
Byte ring buffer with a fixed capacity of N bytes.
Definition IPStack.h:76
TinyPPP internals: PPP engine, HDLC framing and the IP stack.
Definition HDLC.h:11
IPAddress toIPAddress(ip4_t ip)
Converts an engine address to an Arduino IPAddress.
Definition PPPEngine.h:1146
ip4_t toIp4(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
Builds an address from its 4 bytes (a.b.c.d)
Definition PPPEngine.h:109