Skip to content

Commit a74dfbd

Browse files
committed
lwIpWrapper: CNetIf add ping command
1 parent 0c597a4 commit a74dfbd

File tree

6 files changed

+173
-3
lines changed

6 files changed

+173
-3
lines changed

Diff for: libraries/Ethernet/src/Ethernet.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -223,4 +223,27 @@ IPAddress CEthernet::dnsServerIP() {
223223
return CLwipIf::getInstance().getDns();
224224
}
225225

226+
/* -------------------------------------------------------------------------- */
227+
int CEthernet::ping(IPAddress ip, uint8_t ttl) {
228+
/* -------------------------------------------------------------------------- */
229+
return CLwipIf::getInstance().ping(ip, ttl);
230+
}
231+
232+
/* -------------------------------------------------------------------------- */
233+
int CEthernet::ping(const String &hostname, uint8_t ttl)
234+
/* -------------------------------------------------------------------------- */
235+
{
236+
return ping(hostname.c_str(), ttl);
237+
}
238+
239+
/* -------------------------------------------------------------------------- */
240+
int CEthernet::ping(const char* host, uint8_t ttl) {
241+
/* -------------------------------------------------------------------------- */
242+
IPAddress ip;
243+
if(CLwipIf::getInstance().getHostByName(host,ip)) {
244+
return CLwipIf::getInstance().ping(ip, ttl);
245+
}
246+
return -1;
247+
}
248+
226249
CEthernet Ethernet;

Diff for: libraries/Ethernet/src/EthernetC33.h

+6
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ class CEthernet {
6969
IPAddress gatewayIP();
7070
IPAddress dnsServerIP();
7171

72+
/*
73+
* PING
74+
*/
75+
int ping(IPAddress ip, uint8_t ttl = 128);
76+
int ping(const String &hostname, uint8_t ttl = 128);
77+
int ping(const char* host, uint8_t ttl = 128);
7278

7379
friend class EthernetClient;
7480
friend class EthernetServer;

Diff for: libraries/WiFi/src/WiFi.cpp

+23-2
Original file line numberDiff line numberDiff line change
@@ -321,12 +321,33 @@ unsigned long CWifi::getTime() {
321321
return 0;
322322
}
323323

324-
325-
326324
void CWifi::setTimeout(unsigned long timeout) {
327325
(void)(timeout);
328326
}
329327

328+
/* -------------------------------------------------------------------------- */
329+
int CWifi::ping(IPAddress ip, uint8_t ttl) {
330+
/* -------------------------------------------------------------------------- */
331+
return CLwipIf::getInstance().ping(ip, ttl);
332+
}
333+
334+
/* -------------------------------------------------------------------------- */
335+
int CWifi::ping(const String &hostname, uint8_t ttl)
336+
/* -------------------------------------------------------------------------- */
337+
{
338+
return ping(hostname.c_str(), ttl);
339+
}
340+
341+
/* -------------------------------------------------------------------------- */
342+
int CWifi::ping(const char* host, uint8_t ttl) {
343+
/* -------------------------------------------------------------------------- */
344+
IPAddress ip;
345+
if(hostByName(host,ip)) {
346+
return CLwipIf::getInstance().ping(ip, ttl);
347+
}
348+
return -1;
349+
}
350+
330351

331352
CWifi WiFi;
332353

Diff for: libraries/WiFi/src/WiFiC3.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,12 @@ class CWifi {
254254

255255

256256
void setTimeout(unsigned long timeout);
257-
257+
/*
258+
* PING
259+
*/
260+
int ping(IPAddress ip, uint8_t ttl = 128);
261+
int ping(const String &hostname, uint8_t ttl = 128);
262+
int ping(const char* host, uint8_t ttl = 128);
258263

259264
};
260265

Diff for: libraries/lwIpWrapper/src/CNetIf.cpp

+105
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#include "CNetIf.h"
22
#include <functional>
3+
#include "lwip/include/lwip/raw.h"
4+
#include "lwip/include/lwip/icmp.h"
5+
#include "lwip/include/lwip/ip_addr.h"
6+
#include "lwip/include/lwip/inet_chksum.h"
37

48
IPAddress CNetIf::default_ip("192.168.0.10");
59
IPAddress CNetIf::default_nm("255.255.255.0");
@@ -14,6 +18,32 @@ bool CLwipIf::pending_eth_rx = false;
1418

1519
FspTimer CLwipIf::timer;
1620

21+
u8_t icmp_receive_callback(void* arg, struct raw_pcb* pcb, struct pbuf* p, const ip_addr_t* addr)
22+
{
23+
struct ping_data *d = (struct ping_data*)arg;
24+
struct __attribute__((__packed__)) {
25+
struct ip_hdr ipHeader;
26+
struct icmp_echo_hdr header;
27+
} response;
28+
29+
if(d->s == pcb) {
30+
if(p->len < sizeof(response)) {
31+
pbuf_free(p);
32+
return 1;
33+
}
34+
35+
pbuf_copy_partial(p, &response, sizeof(response), 0);
36+
37+
if(response.header.id == d->echo_req.id && response.header.seqno == d->echo_req.seqno) {
38+
d->endMillis = millis();
39+
}
40+
pbuf_free(p);
41+
return 1;
42+
}
43+
44+
return 0;
45+
}
46+
1747
ip_addr_t* u8_to_ip_addr(uint8_t* ipu8, ip_addr_t* ipaddr)
1848
{
1949
IP_ADDR4(ipaddr, ipu8[0], ipu8[1], ipu8[2], ipu8[3]);
@@ -120,6 +150,81 @@ void CLwipIf::lwip_task()
120150
}
121151
}
122152

153+
int CLwipIf::ping(IPAddress ip, uint8_t ttl)
154+
{
155+
uint32_t result = -1;
156+
uint32_t timeout = 5000;
157+
uint32_t sendTime = 0;
158+
uint32_t startWait = 0;
159+
struct pbuf *p;
160+
struct raw_pcb* s;
161+
struct ping_data *d = new ping_data;
162+
if (!d){
163+
goto exit;
164+
}
165+
166+
//Create a raw socket
167+
s = raw_new(IP_PROTO_ICMP);
168+
if(!s) {
169+
goto exit;
170+
}
171+
172+
struct __attribute__((__packed__)) {
173+
struct icmp_echo_hdr header;
174+
uint8_t data[32];
175+
} request;
176+
177+
ICMPH_TYPE_SET(&request.header, ICMP_ECHO);
178+
ICMPH_CODE_SET(&request.header, 0);
179+
request.header.chksum = 0;
180+
request.header.id = 0xAFAF;
181+
request.header.seqno = random(0xffff);
182+
183+
d->echo_req = request.header;
184+
185+
for (size_t i = 0; i < sizeof(request.data); i++) {
186+
request.data[i] = i;
187+
}
188+
189+
request.header.chksum = inet_chksum(&request, sizeof(request));
190+
191+
ip_addr_t addr;
192+
addr.addr = ip;
193+
194+
d->endMillis = 0;
195+
196+
raw_recv(s, icmp_receive_callback, d);
197+
198+
// Build the packet
199+
p = pbuf_alloc(PBUF_IP, sizeof(request), PBUF_RAM);
200+
if (!p) {
201+
goto exit;
202+
}
203+
204+
//Load payload into buffer
205+
pbuf_take(p, &request, sizeof(request));
206+
207+
// Send the echo request
208+
sendTime = millis();
209+
raw_sendto(s, p, &addr);
210+
211+
// Wait for response
212+
startWait = millis();
213+
do {
214+
lwip_task();
215+
} while (d->endMillis == 0 && (millis() - startWait) < timeout);
216+
217+
if (d->endMillis != 0) {
218+
result = d->endMillis - sendTime;
219+
}
220+
221+
exit:
222+
pbuf_free(p);
223+
delete d;
224+
raw_remove(s);
225+
return result;
226+
}
227+
123228
/* -------------------------------------------------------------------------- */
124229
/* GET INSTANCE SINGLETONE FUNCTION */
125230
/* -------------------------------------------------------------------------- */

Diff for: libraries/lwIpWrapper/src/CNetIf.h

+10
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,12 @@ ip_addr_t* u8_to_ip_addr(uint8_t* ipu8, ip_addr_t* ipaddr);
131131

132132
uint32_t ip_addr_to_u32(ip_addr_t* ipaddr);
133133

134+
struct ping_data{
135+
uint32_t endMillis;
136+
icmp_echo_hdr echo_req;
137+
struct raw_pcb* s;
138+
};
139+
134140
/* Base class implements DHCP, derived class will switch it on or off */
135141
/* -------------------------------------------------------------------------- */
136142
class CNetIf {
@@ -436,6 +442,10 @@ class CLwipIf {
436442
int setWifiMode(WifiMode_t mode);
437443

438444
void lwip_task();
445+
/*
446+
* PING
447+
*/
448+
int ping(IPAddress ip, uint8_t ttl = 128);
439449
};
440450

441451
#endif

0 commit comments

Comments
 (0)