Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b83b15c

Browse files
authoredMar 3, 2025··
Merge pull request #424 from fabik111/add-ping-command
Ping command for Portenta C33
2 parents cbac52a + 8094f71 commit b83b15c

File tree

12 files changed

+383
-7
lines changed

12 files changed

+383
-7
lines changed
 

‎extras/net/lwipopts.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@
277277
* (requires the LWIP_RAW option)
278278
*/
279279
#ifndef MEMP_NUM_RAW_PCB
280-
#define MEMP_NUM_RAW_PCB 0
280+
#define MEMP_NUM_RAW_PCB 1
281281
#endif
282282

283283
/**
@@ -642,7 +642,7 @@
642642
* LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
643643
*/
644644
#ifndef LWIP_RAW
645-
#define LWIP_RAW 0
645+
#define LWIP_RAW 1
646646
#endif
647647

648648
/*
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
Web ICMP Ping
3+
4+
This sketch pings a device based on the IP address or the hostname
5+
using the Ethernet module.
6+
7+
created 14 February 2024
8+
by paulvha
9+
10+
updated 27 February 2025
11+
by Fabik111
12+
13+
*/
14+
15+
#include "EthernetC33.h"
16+
17+
int status = WL_IDLE_STATUS;
18+
19+
// Set the static IP address to use if the DHCP fails to assign
20+
IPAddress ip(10, 130, 22, 84);
21+
22+
/* -------------------------------------------------------------------------- */
23+
void setup() {
24+
/* -------------------------------------------------------------------------- */
25+
//Initialize serial and wait for port to open:
26+
Serial.begin(115200);
27+
while (!Serial) {
28+
; // wait for serial port to connect. Needed for native USB port only
29+
}
30+
31+
// start the Ethernet connection:
32+
if (Ethernet.begin() == 0) {
33+
Serial.println("Failed to configure Ethernet using DHCP");
34+
// try to configure using IP address instead of DHCP:
35+
// IN THAT CASE YOU SHOULD CONFIGURE manually THE DNS or USE the IPAddress Server variable above
36+
// that is what is automatically done here...
37+
Ethernet.begin(ip);
38+
}
39+
// give the Ethernet shield a second to initialize:
40+
delay(2000);
41+
}
42+
43+
/* -------------------------------------------------------------------------- */
44+
void loop() {
45+
/* -------------------------------------------------------------------------- */
46+
47+
// Ping IP
48+
const IPAddress remote_ip(140,82,121,4);
49+
Serial.print("Trying to ping github.com on IP: ");
50+
Serial.println(remote_ip);
51+
52+
// using default ping count of 1
53+
int res = Ethernet.ping(remote_ip);
54+
55+
if (res > 0) {
56+
Serial.print("Ping response time: ");
57+
Serial.print(res);
58+
Serial.println(" ms");
59+
}
60+
else {
61+
Serial.println("Timeout on IP!");
62+
}
63+
64+
// Ping Host
65+
const char* remote_host = "www.google.com";
66+
Serial.print("Trying to ping host: ");
67+
Serial.println(remote_host);
68+
69+
// setting ttl to 128 and ping count to 10
70+
int res1 = Ethernet.ping(remote_host);
71+
72+
if (res1 > 0) {
73+
Serial.print("Ping average response time: ");
74+
Serial.print(res1);
75+
Serial.println(" ms");
76+
}
77+
else {
78+
Serial.println("Timeout on host!");
79+
}
80+
81+
Serial.println();
82+
delay(1000);
83+
}

‎libraries/Ethernet/src/Ethernet.cpp

Lines changed: 23 additions & 0 deletions
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;

‎libraries/Ethernet/src/EthernetC33.h

Lines changed: 6 additions & 0 deletions
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;
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
Web ICMP Ping
3+
4+
This sketch pings a device based on the IP address or the hostname
5+
using the WiFi module. By default the attempt is performed 5 times, but can
6+
be changed to max. 255
7+
8+
It requires at least version 0.5.0 of USB Wifi bridge firmware and WiFiS3 library.
9+
10+
This example is written for a network using WPA encryption. For
11+
WEP or WPA, change the WiFi.begin() call accordingly.
12+
13+
created 14 February 2024
14+
by paulvha
15+
16+
updated 27 February 2025
17+
by Fabik111
18+
19+
*/
20+
21+
#include "WiFiC3.h"
22+
#include "arduino_secrets.h"
23+
24+
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
25+
char ssid[] = SECRET_SSID; // your network SSID (name)
26+
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
27+
int keyIndex = 0; // your network key index number (needed only for WEP)
28+
29+
int status = WL_IDLE_STATUS;
30+
31+
/* -------------------------------------------------------------------------- */
32+
void setup() {
33+
/* -------------------------------------------------------------------------- */
34+
//Initialize serial and wait for port to open:
35+
Serial.begin(115200);
36+
while (!Serial) {
37+
; // wait for serial port to connect. Needed for native USB port only
38+
}
39+
40+
// check for the WiFi module:
41+
if (WiFi.status() == WL_NO_MODULE) {
42+
Serial.println("Communication with WiFi module failed.");
43+
// don't continue
44+
while (true);
45+
}
46+
47+
// attempt to connect to WiFi network:
48+
while (status != WL_CONNECTED) {
49+
Serial.print("Attempting to connect to SSID: ");
50+
Serial.println(ssid);
51+
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
52+
status = WiFi.begin(ssid, pass);
53+
54+
// wait 10 seconds for connection:
55+
delay(10000);
56+
}
57+
58+
printWifiStatus();
59+
}
60+
61+
/* -------------------------------------------------------------------------- */
62+
void loop() {
63+
/* -------------------------------------------------------------------------- */
64+
65+
// Ping IP
66+
const IPAddress remote_ip(140,82,121,4);
67+
Serial.print("Trying to ping github.com on IP: ");
68+
Serial.println(remote_ip);
69+
70+
// using default ping count of 1
71+
int res = WiFi.ping(remote_ip);
72+
73+
if (res > 0) {
74+
Serial.print("Ping response time: ");
75+
Serial.print(res);
76+
Serial.println(" ms");
77+
}
78+
else {
79+
Serial.println("Timeout on IP!");
80+
}
81+
82+
// Ping Host
83+
const char* remote_host = "www.google.com";
84+
Serial.print("Trying to ping host: ");
85+
Serial.println(remote_host);
86+
87+
// setting ttl to 128 and ping count to 10
88+
int res1 = WiFi.ping(remote_host);
89+
90+
if (res1 > 0) {
91+
Serial.print("Ping average response time: ");
92+
Serial.print(res1);
93+
Serial.println(" ms");
94+
}
95+
else {
96+
Serial.println("Timeout on host!");
97+
}
98+
99+
Serial.println();
100+
delay(1000);
101+
}
102+
103+
/* -------------------------------------------------------------------------- */
104+
void printWifiStatus() {
105+
/* -------------------------------------------------------------------------- */
106+
// print the SSID of the network you're attached to:
107+
Serial.print("SSID: ");
108+
Serial.println(WiFi.SSID());
109+
110+
// print your board's IP address:
111+
IPAddress ip = WiFi.localIP();
112+
Serial.print("IP Address: ");
113+
Serial.println(ip);
114+
115+
// print the received signal strength:
116+
long rssi = WiFi.RSSI();
117+
Serial.print("signal strength (RSSI):");
118+
Serial.print(rssi);
119+
Serial.println(" dBm");
120+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#define SECRET_SSID ""
2+
#define SECRET_PASS ""

‎libraries/WiFi/src/WiFi.cpp

Lines changed: 23 additions & 2 deletions
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

‎libraries/WiFi/src/WiFiC3.h

Lines changed: 6 additions & 1 deletion
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

‎libraries/lwIpWrapper/src/CNetIf.cpp

Lines changed: 106 additions & 0 deletions
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,33 @@ bool CLwipIf::pending_eth_rx = false;
1418

1519
FspTimer CLwipIf::timer;
1620

21+
static u8_t icmp_receive_callback(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr)
22+
{
23+
struct icmp_echo_hdr *iecho;
24+
(void)(pcb);
25+
(void)(addr);
26+
LWIP_ASSERT("p != NULL", p != NULL);
27+
28+
recv_callback_data* request = (recv_callback_data*)arg;
29+
if ((p->tot_len < (PBUF_IP_HLEN + sizeof(struct icmp_echo_hdr))) ||
30+
pbuf_remove_header(p, PBUF_IP_HLEN) != 0) {
31+
return 0; /* don't consume the packet */
32+
}
33+
34+
iecho = (struct icmp_echo_hdr *)p->payload;
35+
36+
if(iecho->id != 0xAFAF || iecho->seqno != lwip_htons(request->seqNum)) {
37+
/* not eaten, restore original packet */
38+
pbuf_add_header(p, PBUF_IP_HLEN);
39+
return 0;
40+
}
41+
42+
/* do some ping result processing */
43+
request->endMillis = millis();
44+
pbuf_free(p);
45+
return 1; /* consume the packet */
46+
}
47+
1748
ip_addr_t* u8_to_ip_addr(uint8_t* ipu8, ip_addr_t* ipaddr)
1849
{
1950
IP_ADDR4(ipaddr, ipu8[0], ipu8[1], ipu8[2], ipu8[3]);
@@ -120,6 +151,81 @@ void CLwipIf::lwip_task()
120151
}
121152
}
122153

154+
155+
int CLwipIf::ping(IPAddress ip, uint8_t ttl)
156+
{
157+
/* ttl is not supported. Default value used is 255 */
158+
(void)ttl;
159+
ip_addr_t addr;
160+
addr.addr = ip;
161+
162+
/* ICMP ping callback data structure */
163+
static recv_callback_data requestCbkData;
164+
165+
/* initialize callback data for a new request */
166+
memset(&requestCbkData, 0, sizeof(recv_callback_data));
167+
requestCbkData.seqNum = (uint16_t)random(0xffff);
168+
169+
/* Create a raw socket */
170+
struct raw_pcb* s = raw_new(IP_PROTO_ICMP);
171+
if (!s) {
172+
return -1;
173+
}
174+
175+
raw_recv(s, icmp_receive_callback, (void*)&requestCbkData);
176+
raw_bind(s, IP_ADDR_ANY);
177+
178+
struct pbuf *p;
179+
struct icmp_echo_hdr *iecho;
180+
size_t ping_size = sizeof(struct icmp_echo_hdr) + 32;
181+
182+
p = pbuf_alloc(PBUF_IP, (u16_t)ping_size, PBUF_RAM);
183+
if (!p) {
184+
raw_remove(s);
185+
return -1;
186+
}
187+
188+
if ((p->len == p->tot_len) && (p->next == NULL)) {
189+
iecho = (struct icmp_echo_hdr *)p->payload;
190+
191+
size_t i;
192+
size_t data_len = ping_size - sizeof(struct icmp_echo_hdr);
193+
194+
ICMPH_TYPE_SET(iecho, ICMP_ECHO);
195+
ICMPH_CODE_SET(iecho, 0);
196+
iecho->chksum = 0;
197+
iecho->id = 0xAFAF;
198+
iecho->seqno = lwip_htons(requestCbkData.seqNum);
199+
200+
/* fill the additional data buffer with some data */
201+
for(i = 0; i < data_len; i++) {
202+
((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
203+
}
204+
205+
iecho->chksum = inet_chksum(iecho, ping_size);
206+
requestCbkData.startMillis = millis();
207+
raw_sendto(s, p, &addr);
208+
209+
}
210+
pbuf_free(p);
211+
212+
CLwipIf::getInstance().startSyncRequest();
213+
214+
while (!requestCbkData.endMillis && (millis() - requestCbkData.startMillis) <= 5000) {
215+
CLwipIf::getInstance().lwip_task();
216+
}
217+
218+
CLwipIf::getInstance().restartAsyncRequest();
219+
220+
raw_remove(s);
221+
222+
if (!requestCbkData.endMillis) {
223+
return -1;
224+
}
225+
226+
return requestCbkData.endMillis - requestCbkData.startMillis;
227+
}
228+
123229
/* -------------------------------------------------------------------------- */
124230
/* GET INSTANCE SINGLETONE FUNCTION */
125231
/* -------------------------------------------------------------------------- */

‎libraries/lwIpWrapper/src/CNetIf.h

Lines changed: 10 additions & 0 deletions
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 recv_callback_data{
135+
u32_t startMillis;
136+
u32_t endMillis;
137+
u16_t seqNum;
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
3.79 KB
Binary file not shown.

‎libraries/lwIpWrapper/src/lwipopts.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@
273273
* (requires the LWIP_RAW option)
274274
*/
275275
#ifndef MEMP_NUM_RAW_PCB
276-
#define MEMP_NUM_RAW_PCB 0
276+
#define MEMP_NUM_RAW_PCB 1
277277
#endif
278278

279279
/**
@@ -633,7 +633,7 @@
633633
* LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
634634
*/
635635
#ifndef LWIP_RAW
636-
#define LWIP_RAW 0
636+
#define LWIP_RAW 1
637637
#endif
638638

639639
/*

0 commit comments

Comments
 (0)
Please sign in to comment.