forked from arduino/ArduinoCore-renesas
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCNetIf.h
458 lines (367 loc) · 12.6 KB
/
CNetIf.h
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
#pragma once
#define UNUSED(x) (void)(x)
#define USE_LWIP_AS_LIBRARY
#include "Arduino.h"
#include "CCtrlWrapper.h"
#include "CEspControl.h"
#include "IPAddress.h"
#include "EthernetDriver.h"
#include <string>
#include <interface.h>
#ifdef USE_LWIP_AS_LIBRARY
#include "lwip/include/lwip/dhcp.h"
#include "lwip/include/lwip/dns.h"
#include "lwip/include/lwip/init.h"
#include "lwip/include/lwip/ip_addr.h"
#include "lwip/include/lwip/opt.h"
#include "lwip/include/lwip/prot/dhcp.h"
#include "lwip/include/lwip/tcp.h"
#include "lwip/include/lwip/timeouts.h"
#include "lwip/include/lwip/udp.h"
#include "lwip/include/netif/ethernet.h"
#else
#include "lwIP_Arduino.h"
#endif
#define LWIP_USE_TIMER
#ifdef LWIP_USE_TIMER
#include "FspTimer.h"
#endif
#define MAX_SOFAT_CONNECTION_DEF 5
#define MAC_ADDRESS_DIM 6
#define NETWORK_INTERFACES_MAX_NUM 3
#define MAX_HOSTNAME_DIM 253
#define WIFI_INIT_TIMEOUT_MS 10000
#define WL_MAC_ADDR_LENGTH 6
typedef enum {
WL_NO_SHIELD = 255,
WL_NO_MODULE = WL_NO_SHIELD,
WL_IDLE_STATUS = 0,
WL_NO_SSID_AVAIL,
WL_SCAN_COMPLETED,
WL_CONNECTED,
WL_CONNECT_FAILED,
WL_CONNECTION_LOST,
WL_DISCONNECTED,
WL_AP_LISTENING,
WL_AP_CONNECTED,
WL_AP_FAILED
} WifiStatus_t;
/* Encryption modes */
enum wl_enc_type {
ENC_TYPE_WEP,
ENC_TYPE_WPA,
ENC_TYPE_TKIP = ENC_TYPE_WPA,
ENC_TYPE_WPA2,
ENC_TYPE_CCMP = ENC_TYPE_WPA2,
ENC_TYPE_WPA2_ENTERPRISE,
ENC_TYPE_WPA3,
ENC_TYPE_NONE,
ENC_TYPE_AUTO,
ENC_TYPE_UNKNOWN = 255
};
typedef enum {
NI_WIFI_STATION,
NI_WIFI_SOFTAP,
NI_ETHERNET
} NetIfType_t;
enum LinkStatus {
Unknown,
LinkON,
LinkOFF
};
enum EthernetHardwareStatus {
EthernetNoHardware,
EthernetLwip = 7
};
#define MAX_CLIENT MEMP_NUM_TCP_PCB
#define MAX_DHCP_TRIES 4
#define TIMEOUT_DNS_REQUEST 10000U
#define DHCP_CHECK_NONE (0)
#define DHCP_CHECK_RENEW_FAIL (1)
#define DHCP_CHECK_RENEW_OK (2)
#define DHCP_CHECK_REBIND_FAIL (3)
#define DHCP_CHECK_REBIND_OK (4)
#define TIMED_OUT -1
#define INVALID_SERVER -2
#define TRUNCATED -3
#define INVALID_RESPONSE -4
class CLwipIf;
/* Base class implements DHCP, derived class will switch it on or off */
class CNetIf: public NetworkInterface {
public:
CNetIf(NetworkDriver *driver=nullptr);
virtual ~CNetIf() {}
/*
* The begin function is called by the user in the sketch to initialize the network interface
* that he is planning on using in the sketch.
*/
virtual int begin(
const IPAddress &ip = INADDR_NONE,
const IPAddress &nm = INADDR_NONE,
const IPAddress &gw = INADDR_NONE);
/*
* This method performs interface specific tasks (if any)
*/
virtual void task();
#ifdef LWIP_DHCP
/* --------------
* DHCP functions
* -------------- */
// starts DHCP and tries to acquire addresses, return true if request was made successfully (ususally memory issues)
bool dhcpStart();
// stops DHCP
void dhcpStop();
// tells DHCP server that the interface uses a statically provided ip address
void dhcpNotUsed();
// force DHCP renewal, returns false on error (ususally memory issues)
bool dhcpRenew();
// force DHCP release, usually called before dhcp stop (ususally memory issues)
bool dhcpRelease();
// tells if DHCP has acquired addresses or not
bool isDhcpAcquired();
#endif
virtual void setLinkUp();
virtual void setLinkDown();
virtual void up();
virtual void down();
inline int disconnect() { this->down(); return 0; }
inline LinkStatus linkStatus() { return netif_is_link_up(&ni) ? LinkON : LinkOFF; }
bool isLinkUp() { return (bool)netif_is_link_up(&ni); }
struct netif* getNi() { return ∋ }
uint32_t getIpAdd() { return ip4_addr_get_u32(&(ni.ip_addr)); }
uint32_t getNmAdd() { return ip4_addr_get_u32(&(ni.netmask)); }
uint32_t getGwAdd() { return ip4_addr_get_u32(&(ni.gw)); }
// FIXME when dhcp has not provided an ip address yet return IPADDR_NONE
IPAddress localIP() { return IPAddress(this->getIpAdd()); }
IPAddress subnetMask() { return IPAddress(this->getNmAdd()); }
IPAddress gatewayIP() { return IPAddress(this->getGwAdd()); }
IPAddress dnsServerIP();
void config(IPAddress _ip, IPAddress _gw, IPAddress _nm);
virtual int getMacAddress(uint8_t* mac) = 0;
virtual int setMacAddress(uint8_t* mac) = 0;
friend CLwipIf;
protected:
struct netif ni;
#ifdef LWIP_DHCP
volatile bool dhcp_acquired;
#endif
/*
* this function is used to initialize the netif structure of lwip
*/
virtual err_t init(struct netif* ni) = 0;
/*
* This function is passed to lwip and used to send a buffer to the driver in order to transmit it
*/
virtual err_t output(struct netif* ni, struct pbuf* p) = 0;
// the following functions are used to call init and output from lwip in the object context in the C code
friend err_t _netif_init(struct netif* ni);
friend err_t _netif_output(struct netif* ni, struct pbuf* p);
// IPAddress _dnsServerAddress;
// Driver interface pointer
NetworkDriver *driver = nullptr;
void linkDownCallback();
void linkUpCallback();
};
class CEth : public CNetIf {
public:
CEth(NetworkDriver *driver=nullptr);
// virtual ~CEth();
virtual int begin(
const IPAddress &ip = INADDR_NONE,
const IPAddress &nm = INADDR_NONE,
const IPAddress &gw = INADDR_NONE,
const IPAddress &dns = INADDR_NONE);
// The following are overloaded begin methods kept for retrocompatibility with other Arduino cores
// Initialise the Ethernet shield to use the provided MAC address and gain the rest of the
// configuration through DHCP.
// Returns 0 if the DHCP configuration failed, and 1 if it succeeded
virtual int begin(
uint8_t *mac_address,
const IPAddress &local_ip = INADDR_NONE,
const IPAddress &dns_server = INADDR_NONE,
const IPAddress &gateway = INADDR_NONE,
const IPAddress &subnet = INADDR_NONE,
const unsigned long timeout = 60000,
const unsigned long responseTimeout = 4000);
virtual int begin(
uint8_t *mac_address,
const unsigned long timeout = 60000,
const unsigned long responseTimeout = 4000);
virtual int getMacAddress(uint8_t* mac) override {
UNUSED(mac); // FIXME not implemented
return 1;
}
virtual int setMacAddress(uint8_t* mac) override {
UNUSED(mac); // FIXME not implemented
return 1;
}
int maintain() {} // Deprecated method for retrocompatibility
void schedule(void) {} // Deprecated method for retrocompatibility
inline EthernetHardwareStatus hardwareStatus() { return EthernetLwip; }
protected:
/*
* this function is used to initialize the netif structure of lwip
*/
err_t init(struct netif* ni) override;
/*
* This function is passed to lwip and used to send a buffer to the driver in order to transmit it
*/
err_t output(struct netif* ni, struct pbuf* p) override;
static const char eth_ifname[];
private:
/*
* This function is passed to the driver class and it is meant to
* take a pointer to a buffer, and pass it to lwip to process it
*/
void consume_callback(uint8_t* buffer, uint32_t len);
};
class CWifiStation : public CNetIf {
public:
CWifiStation();
virtual ~CWifiStation();
virtual int begin(
const IPAddress &ip = INADDR_NONE,
const IPAddress &nm = INADDR_NONE,
const IPAddress &gw = INADDR_NONE) override;
int connectToAP(const char* ssid, const char *passphrase=nullptr);
int disconnectFromAp();
int scanForAp();
virtual void task() override;
virtual int getMacAddress(uint8_t* mac) override {
// FIXME not implemented
}
virtual int setMacAddress(uint8_t* mac) override {
UNUSED(mac); // FIXME not implemented
return 1;
}
virtual const char* getSSID();
virtual uint8_t* getBSSID(uint8_t* bssid);
virtual int32_t getRSSI();
virtual uint8_t getEncryptionType();
virtual uint8_t getChannel();
const char* getSSID(uint8_t i);
int32_t getRSSI(uint8_t i);
uint8_t getEncrType(uint8_t i);
uint8_t* getBSSID(uint8_t i, uint8_t* bssid);
uint8_t getChannel(uint8_t i);
int setLowPowerMode();
int resetLowPowerMode();
inline WifiStatus_t status() {
return wifi_status;
}
protected:
static const char wifistation_ifname[];
/*
* this function is used to initialize the netif structure of lwip
*/
err_t init(struct netif* ni) override;
/*
* This function is passed to lwip and used to send a buffer to the driver in order to transmit it
*/
err_t output(struct netif* ni, struct pbuf* p) override;
private:
std::vector<AccessPoint_t> access_points;
WifiApCfg_t access_point_cfg;
bool hw_init; // TODO this should be moved to the wifi driver class
WifiStatus_t wifi_status = WL_IDLE_STATUS; // TODO this should be moved to the wifi driver class
};
class CWifiSoftAp : public CNetIf {
public:
CWifiSoftAp();
virtual ~CWifiSoftAp();
virtual int begin(
const IPAddress &ip = INADDR_NONE,
const IPAddress &nm = INADDR_NONE,
const IPAddress &gw = INADDR_NONE) override;
virtual void task() override;
int startSoftAp(const char* ssid, const char* passphrase=nullptr, uint8_t channel=0);
int stopSoftAp();
virtual int getMacAddress(uint8_t* mac) override {
// FIXME not implemented
}
virtual int setMacAddress(uint8_t* mac) override {
UNUSED(mac); // FIXME not implemented
return 1;
}
virtual const char* getSSID();
virtual uint8_t* getBSSID(uint8_t* bssid);
virtual uint8_t getEncryptionType();
virtual uint8_t getChannel();
int setLowPowerMode();
int resetLowPowerMode();
protected:
static const char softap_ifname[];
/*
* this function is used to initialize the netif structure of lwip
*/
err_t init(struct netif* ni);
/*
* This function is passed to lwip and used to send a buffer to the driver in order to transmit it
*/
err_t output(struct netif* ni, struct pbuf* p);
private:
std::vector<AccessPoint_t> access_points;
SoftApCfg_t soft_ap_cfg;
bool hw_init; // TODO this should be moved to the wifi driver class
};
class CLwipIf {
public:
CLwipIf(CLwipIf const&) = delete;
void operator=(CLwipIf const&) = delete;
static CLwipIf& getInstance() {
//FIXME this doesn't to seem good
static CLwipIf instance; // this is private in case we need to synch the access to the singleton
return instance;
}
// run polling tasks from all the LWIP Network Interfaces
// this needs to be called in the loop() if we are not running it
// with a timer
void task();
// Function that provides a Client of the correct kind given the protocol provided in url
// Client* connect(std::string url);
// void request(std::string url, std::function<void(uint8_t*, size_t)>);
// function for setting an iface as default
void setDefaultIface(CNetIf* iface);
// TODO get iface method
// functions that handle DNS resolution
// DNS servers are also set by dhcp
#if LWIP_DNS
// add a dns server, priority set to 0 means it is the first being queried, -1 means the last
uint8_t addDnsServer(const IPAddress& aDNSServer, int8_t priority=-1);
void clearDnsServers();
IPAddress getDns(int n);
// DNS resolution works with a callback if the resolution doesn't return immediately
int getHostByName(const char* aHostname, IPAddress& aResult, bool execute_task=false); // blocking call
int getHostByName(const char* aHostname, std::function<void(const IPAddress&)> cbk); // callback version
#endif
private:
CLwipIf();
~CLwipIf();
// TODO define a Timer for calling tasks
std::vector<CNetIf*> ifaces;
virtual void add_iface(CNetIf* iface);
// virtual void del_iface(CNetIf* iface);
// lwip stores the netif in a linked list called: netif_list
friend class CNetIf;
friend class CWifiSoftAp;
friend class CWifiStation;
public:
#ifdef LWIP_USE_TIMER
FspTimer timer;
inline void syncTimer() {
timer.disable_overflow_irq();
this->task();
}
inline void enableTimer() {
timer.enable_overflow_irq();
}
#else // LWIP_USE_TIMER
inline void syncTimer() {
this->task();
}
inline void enableTimer() { }
#endif // LWIP_USE_TIMER
};
extern CEth Ethernet;
extern CWifiStation WiFiStation;
extern CWifiSoftAp WiFiSoftAP;