TinyPPP
PPP networking over any Arduino Stream
Loading...
Searching...
No Matches
TinyPPP_RP2040.h
Go to the documentation of this file.
1#pragma once
13#include <Arduino.h>
14#include <LwipEthernet.h>
15#include <LwipIntf.h>
16#include <WiFi.h>
17#include <lwip/dns.h>
18#include <lwip/ip4.h>
19#include <lwip/netif.h>
20#include <lwip/pbuf.h>
21
22#include <functional>
23
24#include "PPPEngine.h"
25
26extern std::function<void(struct netif *)> _addNetifCB;
27extern std::function<void(struct netif *)> _removeNetifCB;
28
29namespace tinyppp {
30
32using PPPClient = WiFiClient;
33using PPPServer = WiFiServer;
34using PPPUDP = WiFiUDP;
35
40class TinyPPP_RP2040 : public LwipIntf, protected PPPEngine {
41 public:
42 TinyPPP_RP2040() = default;
43 TinyPPP_RP2040(const TinyPPP_RP2040 &) = delete;
46
52 bool begin(Stream &io) {
53 if (_netifAdded) end();
54 _io = &io;
55
58 memset(&_netif, 0, sizeof(_netif));
59 if (!netif_add(&_netif, &any, &any, &any, this, netifInit, ip4_input)) {
60 return false;
61 }
62 _netifAdded = true;
64
65 // the engine is started from the lwIP context in the packet handler
67 _phID = __addEthernetPacketHandler([this] { this->poll(); });
68 return true;
69 }
70
72 void end() {
73 if (!_netifAdded) return;
74 if (_phID >= 0) {
76 // wait for the handler to send the LCP Terminate-Request
78 while (_cmd != Cmd::None && millis() - start < 1000) delay(1);
80 _phID = -1;
81 }
84 _netifAdded = false;
85 }
86
100
102 using PPPEngine::phase;
107 using PPPEngine::stats;
108
111
113 void setDefault(bool flag = true) {
114 _default = flag;
116 }
117
121
125 while (!connected()) {
126 if (millis() - start >= timeoutMs) return false;
127 delay(10);
128 }
129 return true;
130 }
131
133 bool connected() const { return _up; }
136 if (!_netifAdded) return WL_NO_SHIELD;
138 }
146 IPAddress dnsIP(int n = 0) const {
147 return toIPAddress(n == 0 ? dns1() : dns2());
148 }
149
151 using StateCallback = void (*)(bool up, void *ref);
152
155 void onStateChange(StateCallback cb, void *ref = nullptr) {
157 _stateRef = ref;
158 }
159
161 struct netif *getNetIf() { return &_netif; }
162
163 protected:
164 enum class Cmd : uint8_t { None, Start, Stop };
165
166 struct netif _netif;
167 Stream *_io = nullptr;
168 int _phID = -1;
169 volatile Cmd _cmd = Cmd::None;
170 volatile bool _up = false;
171 bool _netifAdded = false;
172 bool _default = true;
174 void *_stateRef = nullptr;
175
176 // called by the lwIP background task (lwIP lock held)
177 void poll() {
178 if (_cmd == Cmd::Start) {
179 start(*_io);
180 _cmd = Cmd::None;
181 } else if (_cmd == Cmd::Stop) {
182 stop();
183 _cmd = Cmd::None;
184 return;
185 }
186 process();
187 }
188
189 static err_t netifInit(struct netif *netif) {
190 netif->name[0] = 'p';
191 netif->name[1] = 'p';
192 netif->mtu = 1500;
193 netif->flags = 0; // point-to-point: no ARP, no broadcast
194 netif->output = output4;
195#if LWIP_IPV6
196 netif->output_ip6 = output6;
197#endif
198 return ERR_OK;
199 }
200
201 static err_t output4(struct netif *netif, struct pbuf *p,
202 const ip4_addr_t *addr) {
203 (void)addr;
204 TinyPPP_RP2040 *self = (TinyPPP_RP2040 *)netif->state;
205 if (!self->beginIPv4()) return ERR_CONN;
206 for (struct pbuf *q = p; q != nullptr; q = q->next) {
207 self->writeIPv4((const uint8_t *)q->payload, q->len);
208 if (q->len == q->tot_len) break;
209 }
210 return self->endIPv4() ? ERR_OK : ERR_IF;
211 }
212
213#if LWIP_IPV6
214 static err_t output6(struct netif *, struct pbuf *, const ip6_addr_t *) {
215 return ERR_IF; // IPV6CP is not supported
216 }
217#endif
218
219 void onIPv4Packet(const uint8_t *data, size_t len) override {
221 if (p == nullptr) return;
222 pbuf_take(p, data, (u16_t)len);
223 if (_netif.input(p, &_netif) != ERR_OK) pbuf_free(p);
224 }
225
226 void onLinkUp() override {
230 ip4_addr_set_u32(&mask, 0xFFFFFFFF);
232 _netif.mtu = mtu();
235 if (dns1() != 0) {
238 dns_setserver(0, &dns);
239 }
240 if (dns2() != 0) {
243 dns_setserver(1, &dns);
244 }
246 _up = true;
248 }
249
250 void onLinkDown() override {
251 _up = false;
258 }
259};
260
262using TinyPPP = TinyPPP_RP2040;
263
264} // namespace tinyppp
std::function< void(struct netif *)> _removeNetifCB
std::function< void(struct netif *)> _addNetifCB
Portable PPP engine: LCP, PAP client and IPCP over an Arduino Stream.
Definition PPPEngine.h:134
void writeIPv4(const uint8_t *data, size_t len)
Adds data to the packet started with beginIPv4()
Definition PPPEngine.h:266
void start(Stream &io)
Starts the PPP negotiation on the indicated stream.
Definition PPPEngine.h:165
void process()
Reads available input and runs the timers: call frequently.
Definition PPPEngine.h:196
void setOfferedDNS(ip4_t dns1, ip4_t dns2=0)
DNS servers to offer the peer if it asks for them (server role)
Definition PPPEngine.h:143
void setLocalIP(ip4_t ip)
Optional static address configuration. 0 = negotiate with the peer.
Definition PPPEngine.h:139
uint32_t fcsErrors() const
Number of received frames with a wrong FCS.
Definition PPPEngine.h:298
ip4_t localIP() const
Our IP address (0 if not negotiated yet)
Definition PPPEngine.h:286
void setLogger(Print *log)
Debug output (nullptr to disable)
Definition PPPEngine.h:162
void setEchoInterval(uint32_t ms, uint8_t maxFailures=3)
LCP echo keep-alive: 0 disables it.
Definition PPPEngine.h:157
ip4_t dns2() const
Second DNS server received from the peer.
Definition PPPEngine.h:292
PPPPhase phase() const
Current link phase.
Definition PPPEngine.h:284
ip4_t dns1() const
First DNS server received from the peer.
Definition PPPEngine.h:290
void setPeerIP(ip4_t ip)
Address to assign to the peer if it requests one (server role)
Definition PPPEngine.h:141
void stop()
Closes the link gracefully (sends LCP Terminate-Request)
Definition PPPEngine.h:180
void setCredentials(const char *user, const char *password)
PAP credentials (used only if the peer requires authentication)
Definition PPPEngine.h:150
ip4_t peerIP() const
IP address of the peer.
Definition PPPEngine.h:288
bool beginIPv4()
Streaming API for chained buffers (e.g. lwIP pbuf)
Definition PPPEngine.h:260
void setRequestDNS(bool flag)
Request DNS servers from the peer (default true)
Definition PPPEngine.h:148
bool endIPv4()
Sends the packet started with beginIPv4()
Definition PPPEngine.h:268
void setPassive(bool passive)
Passive: do not send LCP requests before the peer starts negotiating.
Definition PPPEngine.h:155
uint16_t mtu() const
MTU we may use for sending (peer MRU)
Definition PPPEngine.h:294
const PPPStats & stats() const
Frame and packet counters.
Definition PPPEngine.h:296
Byte ring buffer with a fixed capacity of N bytes.
Definition IPStack.h:76
PPP network interface for RP2040 / RP2350 (arduino-pico): the TinyPPP engine registered as a point-to...
Definition TinyPPP_RP2040.h:40
struct netif * getNetIf()
The lwIP netif of the interface.
Definition TinyPPP_RP2040.h:161
bool begin(Stream &io)
Definition TinyPPP_RP2040.h:52
~TinyPPP_RP2040()
Definition TinyPPP_RP2040.h:45
IPAddress subnetMask() const
Always 255.255.255.255 (point-to-point link)
Definition TinyPPP_RP2040.h:144
void * _stateRef
Definition TinyPPP_RP2040.h:174
TinyPPP_RP2040(const TinyPPP_RP2040 &)=delete
bool _default
Definition TinyPPP_RP2040.h:172
void onLinkUp() override
Called when IPCP is opened: addresses are available.
Definition TinyPPP_RP2040.h:226
void setDefault(bool flag=true)
Make this interface the default route when the link is up (default true)
Definition TinyPPP_RP2040.h:113
volatile bool _up
Definition TinyPPP_RP2040.h:170
volatile Cmd _cmd
Definition TinyPPP_RP2040.h:169
bool waitConnected(uint32_t timeoutMs=30000)
Waits until the link is up.
Definition TinyPPP_RP2040.h:123
IPAddress localIP() const
Our IP address.
Definition TinyPPP_RP2040.h:140
wl_status_t status() const
WL_CONNECTED when the link is up, WL_NO_SHIELD before begin()
Definition TinyPPP_RP2040.h:135
Cmd
Definition TinyPPP_RP2040.h:164
bool _netifAdded
Definition TinyPPP_RP2040.h:171
static err_t output4(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr)
Definition TinyPPP_RP2040.h:201
StateCallback _stateCallback
Definition TinyPPP_RP2040.h:173
void poll()
Definition TinyPPP_RP2040.h:177
bool connected() const
true when the link is up and has an IP address
Definition TinyPPP_RP2040.h:133
Stream * _io
Definition TinyPPP_RP2040.h:167
int _phID
Definition TinyPPP_RP2040.h:168
void end()
Terminates the link and removes the interface.
Definition TinyPPP_RP2040.h:72
bool config(IPAddress local, IPAddress peer=IPAddress(0, 0, 0, 0), IPAddress dns1=IPAddress(0, 0, 0, 0), IPAddress dns2=IPAddress(0, 0, 0, 0))
Definition TinyPPP_RP2040.h:92
void onIPv4Packet(const uint8_t *data, size_t len) override
Called for each received IPv4 packet.
Definition TinyPPP_RP2040.h:219
void setLogger(Print &out)
Debug output e.g. setLogger(Serial1)
Definition TinyPPP_RP2040.h:110
void onStateChange(StateCallback cb, void *ref=nullptr)
Definition TinyPPP_RP2040.h:155
IPAddress dnsIP(int n=0) const
The DNS server n (0 or 1) received from the peer.
Definition TinyPPP_RP2040.h:146
TinyPPP_RP2040 & operator=(const TinyPPP_RP2040 &)=delete
void onLinkDown() override
Called when the IP link goes down.
Definition TinyPPP_RP2040.h:250
void setPollingPeriod(int ms)
Definition TinyPPP_RP2040.h:120
IPAddress gatewayIP() const
The IP address of the peer.
Definition TinyPPP_RP2040.h:142
struct netif _netif
Definition TinyPPP_RP2040.h:166
static err_t netifInit(struct netif *netif)
Definition TinyPPP_RP2040.h:189
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
NetworkClient PPPClient
Portable aliases for the network classes that work over PPP.
Definition TinyPPP_ESP32.h:31
NetworkUDP PPPUDP
Definition TinyPPP_ESP32.h:33
ip4_t fromIPAddress(const IPAddress &ip)
Converts an Arduino IPAddress to an engine address (0 if not set)
Definition PPPEngine.h:1152
TinyPPP_ESP32 TinyPPP
The PPP network interface of this platform.
Definition TinyPPP_ESP32.h:304
NetworkServer PPPServer
Definition TinyPPP_ESP32.h:32